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

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

问题描述

这是一个工作版本.在我通过 NSCoding 从 NSUserDefaults 保存并加载它之后,我能够在 NSMUtableArray 中检索我的对象.我认为值得一提的是,您不仅需要取消归档阵列,还需要取消归档其所有内容.如您所见,我不仅要存储我的 freeze 对象的 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.

还需要注意的是:当您尝试从 runes 数组中初始化一个新的 Freeze 对象时,您得到的错误是在方法结束时引起的,因为当您将对象放入 runes 数组中,您首先将其封装为 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天全站免登陆