NSUserDefaults、NSCoder、自定义类 - iPhone 应用程序问题
我遇到了错误,我想我在以下过程中做错了什么。首先,我有一个类 Contacts:
@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); 行上,我的程序停止运行。它打印一切正常,甚至打印该对象的类是“Contact”。但随后它就停止了。看起来可能有错误,但在左侧,我只在左侧错误区域的 XCode 4 中的“按线程”选项下看到问号。
那么我做错了什么?
I'm having an error and I guess I'm doing something wrong in the following process. Firstly, I have a class Contacts:
@interface Contact : NSObject<NSCoding> {
@private
ABRecordRef ref;
NSString *first;
NSString *last;
bool selected;
NSString *phoneNumber;
}
And in Contact's implementation, I have:
- (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;
}
And when I create what I call a "group" in my app, I do the following:
+ (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];
}
which, according to some print statements I make, seems to work fine.
Then, when the app launches, I try to print those objects I stored:
+ (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);
}
}
However, on the line NSLog(@"got contact %@",c);, my program stops running. It prints everything fine, and even prints that the object's class is "Contact". But then it stops. It looks like maybe there is an error but on the left hand side I just see question marks under the "By Thread" option in XCode 4 in the error area on the left.
So what am I doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,您的 init 应该如下所示:
在
encodeWithCoder
中,您将first
编码两次,您可能想要在第二个中使用phoneNumber
。也许我错过了您创建新的
Contact
对象的位置,但您可能需要一个标准的init
方法来最初创建联系人(initWithCoder
> 我相信,仅当您从数据或文件解码时才初始化)。这可能看起来像这样:我不确定是否还有其他问题,但尝试更改这两件事,看看是否会产生影响。确保您有一个可以释放所有类成员的
dealloc
。First, your init should look like this:
In
encodeWithCoder
you encodefirst
twice, you probably wantedphoneNumber
in the second one.Maybe I'm missing where you're creating new
Contact
objects, but you will probably want a standardinit
method to create the contact initially (initWithCoder
only initializes when you're decoding from data or a file, I believe). This would probably want to look something like:I'm not sure if anything else is wrong, but try changing these two things and see if it makes a difference. Make sure you have a
dealloc
where you release all of your class members.嗯。事实证明,如果我在解码方法上添加保留,一切都会正常。我的意思是,保留所有对象。
Hm. Turned out if I added a retain on the decode method, everything worked. I mean, retain all the objects.