【问题标题】:NSKeyedUnarchiver objects getting broken?NSKeyedUnarchiver 对象被破坏?
【发布时间】:2010-12-25 12:12:02
【问题描述】:

我有一个要保存到 NSUserDefaults 的数组,其中包含我的自定义类 Assignment 的数组,它符合 NSCoding 协议。数组保存和加载正确,我可以验证检索到的数组的第一个对象是类Assignment。当我尝试访问数组中 Assignment 对象的 ivars 时,就会出现问题。它崩溃了,我收到以下错误:

*** -[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 之前一切都很好,这是发生崩溃的地方。有人有什么想法吗?

编辑:这是我在 Assignment 类中的 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;
}

【问题讨论】:

    标签: objective-c nskeyedarchiver


    【解决方案1】:

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

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

    现在一切都很好。 :)

    【讨论】:

    • 或者如果你定义了属性,你可以使用self.隐式保留它,即self.title = [coder decodeObjectForKey:@"title"];
    • 这显然意味着每个对象,包括 initWithCoder: 方法中的对象。因此,如果取消归档程序在发布时出现段错误,请检查并确保您的对象内部的对象、这些对象内部的对象以及这些对象内部的对象等在取消归档时都被保留。
    猜你喜欢
    • 1970-01-01
    • 2018-02-26
    • 1970-01-01
    • 2020-03-05
    • 2020-11-17
    • 2014-05-26
    • 2020-08-26
    • 1970-01-01
    • 2015-02-14
    相关资源
    最近更新 更多