NSUserDefaults,NSCoder,自定义类 – iPhone应用程序的问题

我有一个错误,我想我在做以下过程中的错误。 首先,我有一个class级联系人:

@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; } 

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

 + (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(@“有联系%@”,c);我的程序停止运行。 它打印一切正常,甚至打印对象的类是“联系”。 但是,然后停止。 它看起来也许有一个错误,但在左侧,我只看到左边的错误区域中的XCode 4中的“按线程”选项下的问号。

那么我做错了什么?

在这里输入图像说明

首先,你的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; } 

encodeWithCoderfirst编码两次,您可能需要第二个中的phoneNumber

也许我错过了创build新的Contact对象的位置,但是您可能需要一个标准的init方法来初始创build联系人( 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你释放所有的类成员。

嗯。 原来,如果我在解码方法上添加了保留,一切工作。 我的意思是,保留所有的对象。