2011-07-14 10 views
0

私はエラーが発生していると私は次のプロセスで何か間違っていると思います。まず、私がクラスの連絡先を持っている:NSUserDefaults、NSCoder、カスタムクラス - iPhoneアプリの質問

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

、コンタクトの実装では、私が持っている:

- (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上( "接触%の@を得た"、C @);,私のプログラムの実行が停止します。それはすべてをうまく印刷し、オブジェクトのクラスが「連絡先」であることも印刷します。しかし、それは停止します。おそらくエラーがあるように見えますが、左側にXcode 4の「By Thread」オプションの下のエラー領域に疑問符が表示されます。

どうしたのですか?

enter image description here

答えて

0

まず、あなたのinitは次のようになります。encodeWithCoder

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

あなたが二回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があることを確認してください。

0

hm。 decodeメソッドでretainを追加すると、すべてが機能しました。つまり、すべてのオブジェクトを保持するということです。

+0

NSZombieを検索すると、それらの問題を見つけるのに役立ちます – bshirley