NSUserDefaults, NSCoder, Custom Class - iPhone app question
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?
First, your init should look like this:
- (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;
}
In encodeWithCoder
you encode first
twice, you probably wanted phoneNumber
in the second one.
Maybe I'm missing where you're creating new Contact
objects, but you will probably want a standard init
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:
- (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;
}
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.
精彩评论