0

我有一个错误,我想我在下面的过程中做错了什么。首先,我有一个班级联系人:

@interface Contact : NSObject<NSCoding> {
    @private
    ABRecordRef ref;
    NSString *first;
    NSString *last;
    bool selected;
    NSString *phoneNumber;
}

在 Contact 的实现中,我有:

- (void)encodeWithCoder:(NSCoder *)encoder {
    [encoder encodeObject:first forKey:@"First"];
    [encoder encodeObject:last forKey:@"Last"];
    [encoder encodeObject:[NSNumber numberWithInteger: ABRecordGetRecordID(ref)] forKey:@"Ref"  ];
    [encoder encodeObject:first forKey:@"PhoneNumber"];
}

- (id)initWithCoder:(NSCoder *)decoder {
    self = [[Contact alloc] init];
    first = [decoder decodeObjectForKey:@"First"];
    last = [decoder decodeObjectForKey:@"Last"];
    ABAddressBookRef addressBook = ABAddressBookCreate();
    NSNumber *num = [decoder decodeObjectForKey:@"Ref"];
    ref = ABAddressBookGetPersonWithRecordID(addressBook,(ABRecordID)num);
    phoneNumber = [decoder decodeObjectForKey:@"PhoneNumber"];

    return self;
}

当我在我的应用程序中创建我所谓的“组”时,我会执行以下操作:

+ (void)addGroupWithName:(NSString *)s contacts:(NSMutableArray *)arr {
    NSLog(@"added group name with name %@",s);
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:arr];
    [defaults setObject:data forKey:s];
    [defaults synchronize];
    //[UserData setDefaultWithName:s object:arr];
}

根据我所做的一些打印声明,这似乎工作正常。

然后,当应用程序启动时,我尝试打印我存储的那些对象:

+ (void)printGroups {
    NSMutableArray *arr = [UserData getGroupNames];
    NSLog(@"group names are %@",arr);
    for(int i = 0; i < [arr count]; i++) {
        NSString *name = [arr objectAtIndex:i];
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        NSData *data = [defaults objectForKey:name];
        NSArray *a = [NSKeyedUnarchiver unarchiveObjectWithData:data];
        NSLog(@"name = %@",name);
        NSLog(@"array count is %i",[a count]);
        for(int i = 0; i < [a count]; i++) {
            NSLog(@"on index %i",i);
            Contact *c = [a objectAtIndex:i];
            NSLog(@"got contact");
            if(c == nil)
                NSLog(@"it's nil!");    

            NSLog(@"class is %@", NSStringFromClass([c class]));
            NSLog(@"got contact %@",c);
        }
        NSLog(@"array = %@",a);
    }
}

但是,在 NSLog(@"got contact %@",c); 行上,我的程序停止运行。它打印一切都很好,甚至打印出对象的类是“联系人”。但随后它停止了。看起来可能有错误,但在左侧,我只在左侧错误区域的 XCode 4 中的“按线程”选项下看到问号。

那么我做错了什么?

在此处输入图像描述

4

2 回答 2

0

嗯。事实证明,如果我在解码方法上添加了保留,一切正常。我的意思是,保留所有对象。

于 2011-07-14T18:34:36.900 回答
0

首先,您的 init 应该如下所示:

- (id)initWithCoder:(NSCoder *)decoder 
{
    if(self = [super init])
    {
        first = [[decoder decodeObjectForKey:@"First"] retain];
        last = [[decoder decodeObjectForKey:@"Last"] retain];
        ABAddressBookRef addressBook = ABAddressBookCreate();
        NSNumber *num = [decoder decodeObjectForKey:@"Ref"];
        ref = ABAddressBookGetPersonWithRecordID(addressBook,(ABRecordID)num);
        phoneNumber = [[decoder decodeObjectForKey:@"PhoneNumber"] retain];
    }

    return self;
}

encodeWithCoder你编码first两次时,你可能想要phoneNumber第二次。

也许我错过了您创建新Contact对象的位置,但您可能需要一个标准init方法来最初创建联系人(initWithCoder我相信只有在您从数据或文件解码时才初始化)。这可能看起来像:

- (id)initWithFirst:(NSString *)firstIn last:(NSString *)lastIn phone:(NSString *)phoneIn 
{
    if(self = [super init])
    {
        first = [firstIn retain];
        last = [lastIn retain]; 
        phoneNumber = [phoneIn retain];
        selected = NO;
        ref = //however you generate a record reference
    }

    return self;
}

我不确定是否还有其他问题,但请尝试更改这两件事,看看是否有所作为。确保你有一个dealloc释放所有班级成员的地方。

于 2011-07-14T18:31:14.487 回答