NSUserDefaults,NSCoder,Custom Class - iPhone应用程序问题 [英] NSUserDefaults, NSCoder, Custom Class - iPhone app question

查看:85
本文介绍了NSUserDefaults,NSCoder,Custom Class - iPhone应用程序问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了错误,我猜我在以下过程中做错了。首先,我有一个班级联系人:

  @interface联系方式:NSObject< NSCoding> {
@private
ABRecordRef ref;
NSString * first;
NSString * last;选择
bool;
NSString * phoneNumber;
}

在Contact的实施中,我有:

   - (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:first forKey:@First];
[encoder encodeObject:last forKey:@Last];
[编码器编码对象:[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];

返回自我;
}

当我在我的应用中创建我称之为群组的内容时,我执行以下操作:

  +(void)addGroupWithName:(NSString *)s contacts:(NSMutableArray *)arr {
NSLog(@添加名称为%@的组名,s);
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
NSData * data = [NSKeyedArchiver archivedDataWithRootObject:arr];
[defaults setObject:data forKey:s];
[默认同步];
// [UserData setDefaultWithName:s object:arr];
}

根据我的一些印刷声明,它似乎工作正常。



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

  +(void)printGroups {
NSMutableArray * arr = [UserData getGroupNames];
NSLog(@组名是%@,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 =%@,姓名);
NSLog(@数组计数为%i,[计数]);
for(int i = 0; i< [a count]; i ++){
NSLog(@on index%i,i);
联系人* c = [a objectAtIndex:i];
NSLog(@联系);
if(c == nil)
NSLog(@它是零!);

NSLog(@class is%@,NSStringFromClass([c class]));
NSLog(@联系%@,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];
}

返回自我;
}

encodeWithCoder 你编码第一次两次,你可能想在第二次 phoneNumber



也许我在你创建新联系对象的地方失踪了,但你可能想要一个标准的 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];选择
=否;
ref = //但是你生成一个记录参考
}

返回self;
}

我不确定是否有其他错误,但请尝试更改这两项事情,看看它是否有所作为。确保你有一个 dealloc ,你释放所有的班级成员。


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.

这篇关于NSUserDefaults,NSCoder,Custom Class - iPhone应用程序问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆