Хорошо, таким образом, я делал некоторый ввод по абсолютному адресу вокруг, и я осознаю свою проблему, но я не знаю, как зафиксировать его. Я сделал пользовательский класс для содержания некоторых данных. Я делаю объекты для этого класса, и я должен им продержаться между сессиями. Прежде чем я вставлял всю свою информацию NSUserDefaults
, но это не работает.
-[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value '<Player: 0x3b0cc90>' of class 'Player'.
Это - сообщение об ошибке, которое я получаю, когда я поместил свой пользовательский класс, "Плеер", в NSUserDefaults
. Теперь, я читал настолько, по-видимому, NSUserDefaults
только хранилища некоторые типы информации. Таким образом, как я получает мои объекты в NSUSerDefaults
?
Я считал, что должен быть путь к "закодировать" мой пользовательский объект и затем вставить его, но я не уверен, как реализовать его, справка ценилась бы!Спасибо!
**** РЕДАКТИРОВАНИЕ ****
Хорошо, таким образом, я работал с кодом, данным ниже (Спасибо!), но у меня все еще есть некоторые проблемы. В основном код отказывает теперь, и я не уверен, почему, потому что он не дает ошибок. Возможно, я пропускаю что-то основное, и я просто также устал, но мы будем видеть. Вот реализация моего Пользовательского класса, "Плеера":
@interface Player : NSObject {
NSString *name;
NSNumber *life;
//Log of player's life
}
//Getting functions, return the info
- (NSString *)name;
- (int)life;
- (id)init;
//These are the setters
- (void)setName:(NSString *)input; //string
- (void)setLife:(NSNumber *)input; //number
@end
Файл реализации:
#import "Player.h"
@implementation Player
- (id)init {
if (self = [super init]) {
[self setName:@"Player Name"];
[self setLife:[NSNumber numberWithInt:20]];
[self setPsnCounters:[NSNumber numberWithInt:0]];
}
return self;
}
- (NSString *)name {return name;}
- (int)life {return [life intValue];}
- (void)setName:(NSString *)input {
[input retain];
if (name != nil) {
[name release];
}
name = input;
}
- (void)setLife:(NSNumber *)input {
[input retain];
if (life != nil) {
[life release];
}
life = input;
}
/* This code has been added to support encoding and decoding my objecst */
-(void)encodeWithCoder:(NSCoder *)encoder
{
//Encode the properties of the object
[encoder encodeObject:self.name forKey:@"name"];
[encoder encodeObject:self.life forKey:@"life"];
}
-(id)initWithCoder:(NSCoder *)decoder
{
self = [super init];
if ( self != nil )
{
//decode the properties
self.name = [decoder decodeObjectForKey:@"name"];
self.life = [decoder decodeObjectForKey:@"life"];
}
return self;
}
-(void)dealloc {
[name release];
[life release];
[super dealloc];
}
@end
Таким образом, это - мой класс, довольно прямой, я знаю, что он работает в создании моих объектов. Таким образом, вот соответствующие части файла AppDelegate (где я называю шифрование и дешифрую функции):
@class MainViewController;
@interface MagicApp201AppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
MainViewController *mainViewController;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) MainViewController *mainViewController;
-(void)saveCustomObject:(Player *)obj;
-(Player *)loadCustomObjectWithKey:(NSString*)key;
@end
И затем важные части файла реализации:
#import "MagicApp201AppDelegate.h"
#import "MainViewController.h"
#import "Player.h"
@implementation MagicApp201AppDelegate
@synthesize window;
@synthesize mainViewController;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
//First check to see if some things exist
int startup = [prefs integerForKey:@"appHasLaunched"];
if (startup == nil) {
//Make the single player
Player *singlePlayer = [[Player alloc] init];
NSLog([[NSString alloc] initWithFormat:@"%@\n%d\n%d",[singlePlayer name], [singlePlayer life], [singlePlayer psnCounters]]); // test
//Encode the single player so it can be stored in UserDefaults
id test = [MagicApp201AppDelegate new];
[test saveCustomObject:singlePlayer];
[test release];
}
[prefs synchronize];
}
-(void)saveCustomObject:(Player *)object
{
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSData *myEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:object];
[prefs setObject:myEncodedObject forKey:@"testing"];
}
-(Player *)loadCustomObjectWithKey:(NSString*)key
{
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSData *myEncodedObject = [prefs objectForKey:key ];
Player *obj = (Player *)[NSKeyedUnarchiver unarchiveObjectWithData: myEncodedObject];
return obj;
}
Eeee, извините обо всем коде. Просто попытка помочь. В основном приложение запустит и затем разрушит immediatly. Я сузил его к части шифрования приложения, это - то, где это отказывает, таким образом, я делаю что-то не так, но я не уверен что. Справка ценилась бы снова, спасибо!
(Я еще не нашел время для дешифрования, поскольку я не получил шифрование еще, работающее.)
В вашем классе Player реализуйте следующие два метода (заменив вызовы encodeObject на что-то, относящееся к вашему собственному объекту):
- (void)encodeWithCoder:(NSCoder *)encoder {
//Encode properties, other class variables, etc
[encoder encodeObject:self.question forKey:@"question"];
[encoder encodeObject:self.categoryName forKey:@"category"];
[encoder encodeObject:self.subCategoryName forKey:@"subcategory"];
}
- (id)initWithCoder:(NSCoder *)decoder {
if((self = [super init])) {
//decode properties, other class vars
self.question = [decoder decodeObjectForKey:@"question"];
self.categoryName = [decoder decodeObjectForKey:@"category"];
self.subCategoryName = [decoder decodeObjectForKey:@"subcategory"];
}
return self;
}
Чтение и запись из NSUserDefaults
:
- (void)saveCustomObject:(MyObject *)object key:(NSString *)key {
NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:object];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:encodedObject forKey:key];
[defaults synchronize];
}
- (MyObject *)loadCustomObjectWithKey:(NSString *)key {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *encodedObject = [defaults objectForKey:key];
MyObject *object = [NSKeyedUnarchiver unarchiveObjectWithData:encodedObject];
return object;
}
Код бесстыдно позаимствован из: сохранения класса в nsuserdefaults