在NSUserDefaults中存储填充了自定义对象的NSMutableArray - 崩溃 [英] Storing NSMutableArray filled with custom objects in NSUserDefaults - crash

查看:152
本文介绍了在NSUserDefaults中存储填充了自定义对象的NSMutableArray - 崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:这是一个工作版本。我通过NSCoding保存并从NSUserDefaults加载后,我能够在NSMUtableArray中检索我的对象。我认为重要的是,您不仅需要对数组进行反存档,还需要对其所有内容进行反存档。正如你所看到的,我不仅要存储我的冻结对象的NSData,还要存储我的数组的NSData:

Here is a working version. I was able to retrieve my object within the NSMUtableArray after I saved and loaded it from the NSUserDefaults via NSCoding. I think it's important to mention, that you not only need to de-archive the array, but also all its content. As you can see, I had to not only store the NSData of my freeze object, but also the NSData of my array:

// My class "Freeze"
@interface Freeze : NSObject <NSCoding> // The NSCoding-protocoll is important!!
{
    NSMutableString *name;
}
@property(nonatomic, copy) NSMutableString *name;

-(void) InitString;
@end

@implementation Freeze
@synthesize name;

-(void) InitString {
    name = [[NSMutableString stringWithString:@"Some sentence... lalala"] retain];
}

// Method from NSCoding-protocol
- (void)encodeWithCoder:(NSCoder *)encoder
{
    //Encode properties, other class variables, etc
    [encoder encodeObject:self.name forKey:@"name"];

}

// Method from NSCoding-protocol
- (id)initWithCoder:(NSCoder *)decoder
{
    self = [super init];
    if( self != nil )
    {
        //decode properties, other class vars
        self.name = [decoder decodeObjectForKey:@"name"];

    }
    return self;
}
@end




Freeze *freeze;
NSMutableArray *runes;
NSMutableArray *newRunes;


runes = [[NSMutableArray alloc] init];
newRunes = [[NSMutableArray alloc] init];

freeze = [[Freeze alloc] init];
[freeze InitString];
[runes addObject:freeze];

[self saveState];
[self restoreState];

Freeze *newFreeze = [[Freeze alloc] init];
newFreeze = [newRunes objectAtIndex:0];
NSString *String = [NSString stringWithString:newFreeze.name];
NSLog(@"%@", String);

//-----------------------------------------------------------------------------

- (void) saveState 
{    
    NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];

    NSData* myClassData = [NSKeyedArchiver archivedDataWithRootObject:freeze];
    [defaults setObject:myClassData forKey:@"MyClass"];

    NSData* myClassArrayData = [NSKeyedArchiver archivedDataWithRootObject:runes];
    [defaults setObject:myClassArrayData forKey:@"MyClassArray"];

}

- (void) restoreState 
{    
    NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];

    NSData* myClassData = [defaults objectForKey:@"MyClass"];
    freeze = [NSKeyedUnarchiver unarchiveObjectWithData:myClassData];

    NSData* myClassArrayData = [defaults objectForKey:@"MyClassArray"];    
    NSArray *savedMyClassArray = [NSKeyedUnarchiver unarchiveObjectWithData:myClassArrayData];
    if( savedMyClassArray != nil ) 
        newRunes = [[NSMutableArray alloc] initWithArray:savedMyClassArray];    
    else
    newRunes =  [[NSMutableArray alloc] init];
}

编辑:这是我之前收到的错误,它没有显示出来以上更新版本。

This is an error I got before, it doesn't show up anymore with the updated version above.

它在最后崩溃,调试器显示以下错误:
* *终止应用程序由于未捕获的异常'NSInvalidArgumentException',原因:' - [NSConcreteMutableData InitString]:无法识别的选择器发送到实例0x6b1fe20'*

It crashes at the very end and the debugger reveals the following error: ** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSConcreteMutableData InitString]: unrecognized selector sent to instance 0x6b1fe20'*

此外,它说NewFreeze是不是CFString类型。有人知道发生了什么吗?我真的想保存我的对象。

Furthermore, it says that "NewFreeze" is not of type CFString. Does anybody have a clue what's going on? I really want to save my Objects like that.

推荐答案

问题是将自定义类存储为Settings plist中的节点( NSUserDefaults是不允许的,因为数据存储在文件系统中而不是应用程序中的对象。设置应用程序(此数据也将可见)不知道冻结对象是什么。处理你想做的事情的最好方法是使用Core Data。

The problem is that storing custom classes as a node in the Settings plist (NSUserDefaults) is not allowed, since the data is stored in the file system rather than an object from the application. The settings app (where this data will also be visible) has no idea what a "Freeze" object is. The best way to handle what you want to do is to probably use Core Data.

还要注意:你得到的错误是在方法结束时引起的。你试图从你的符文数组初始化一个新的冻结对象,因为当你把对象放入符文数组时你首先将它封装为 NSData 对象,但是当你把它取出时,你不要在将它设置为 NewFreeze

also of note: the error you are getting is caused at the end of the method when you try to initalize a new Freeze object from your runes array, because when you put the object into the runes array you encapsulated it as a NSData object first, but when you get it out you don't dearchive it before setting it to NewFreeze

这篇关于在NSUserDefaults中存储填充了自定义对象的NSMutableArray - 崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆