2009-12-11 107 views
0

我有一个数组,我保存到NSUserDefaults,其中包含我的自定义类Assignment,它符合NSCoding协议的数组。数组保存并正确加载,我可以验证数组的检索到的第一个对象是类Assignment。当我尝试访问数组中Assignment对象的ivars时,会发生问题。它崩溃,我得到以下错误:NSKeyedUnarchiver对象被破坏?

*** -[CFString respondsToSelector:]: message sent to deallocated instance 0x3948d60 

这是我用来保存到用户默认值的代码。请注意,我还检索并检查保存的对象以进行调试。

-(void)saveToUserDefaults:(NSArray*)myArray 
{ 
    NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults]; 

    if (standardUserDefaults) { 
     [standardUserDefaults setObject:[NSKeyedArchiver archivedDataWithRootObject:myArray] forKey:@"Assignments"]; 
     [standardUserDefaults synchronize]; 
    } 
    NSLog(@"Assignments array saved. (%d assignments in array)",[myArray count]); 
    NSData *dataCheck = [[NSData alloc] initWithData:[standardUserDefaults objectForKey:@"Assignments"]]; 
    NSArray *arrayCheck = [[NSArray alloc] initWithArray:[NSKeyedUnarchiver unarchiveObjectWithData:dataCheck]]; 
    NSLog(@"Checking saved array (%d assignments in array)",[arrayCheck count]); 
    if ([[arrayCheck objectAtIndex:0] isKindOfClass:[Assignment class]]) { 
     NSLog(@"It's of the class Assignment."); 
    } 
    Assignment *testAssignment = [[Assignment alloc] initWithAssignment:[arrayCheck objectAtIndex:0]]; 
    NSLog(@"Title: %@ Course: %@",[testAssignment title],[testAssignment course]); 
} 

一切都很好,直到我分配testAssignment,这是崩溃发生的地方。有没有人有任何想法?

编辑:这是我的NSCoding方法的分配类:

- (void)encodeWithCoder:(NSCoder *)coder { 
    [coder encodeObject:title forKey:@"title"]; 
    [coder encodeObject:course forKey:@"course"]; 
    [coder encodeObject:dueDate forKey:@"dueDate"]; 
    [coder encodeObject:notes forKey:@"notes"]; 
} 

- (id)initWithCoder:(NSCoder *)coder { 
    self = [[Assignment alloc] init]; 
    if (self != nil) 
    { 
     title = [coder decodeObjectForKey:@"title"]; 
     course = [coder decodeObjectForKey:@"course"]; 
     dueDate = [coder decodeObjectForKey:@"dueDate"]; 
     notes = [coder decodeObjectForKey:@"notes"]; 
    } 
    return self; 
} 

回答

3

回答我自己的问题。在initWithCoder中,我需要保留所有我正在解码的对象:

//Example  
title = [[coder decodeObjectForKey:@"title"] retain]; 

现在一切都很好用。 :)

+1

或者,如果您定义了属性,则可以使用self隐式保留它。,即self.title = [coder decodeObjectForKey:@“title”]; – 2012-01-11 22:05:51

+1

这意味着EVERY OBJECT,显然包括initWithCoder:methods内的对象。因此,如果unarchiver在发布时进行了segfaulting,请通过并确保对象内部的对象,这些对象内部的对象以及这些对象内部的对象等在展开时都保留下来。 – Tustin2121 2012-02-26 05:11:42

+0

@Ben Jakuben:非常感谢,这对我很有用。 – Vjlakshmi 2012-12-07 07:45:47