0

CoreDataで設定した関係に問題があります。その1対多、顧客は多くの連絡先を持つことができます、これらの連絡先は名簿からのものです。

私のモデルは次のようになります。

Customer <---->> Contact
Contact  <-----> Customer

Contact.h

@class Customer;

@interface Contact : NSManagedObject

@property (nonatomic, retain) id addressBookId;
@property (nonatomic, retain) Customer *customer;

@end

Customer.h

@class Contact;

@interface Customer : NSManagedObject

@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSSet *contact;

@end

@interface Customer (CoreDataGeneratedAccessors)

- (void)addContactObject:(Contact *)value;
- (void)removeContactObject:(Contact *)value;
- (void)addContact:(NSSet *)values;
- (void)removeContact:(NSSet *)values;

@end

そして、保存しようとしています:

AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
Customer *customer = (Customer *)[NSEntityDescription insertNewObjectForEntityForName:@"Customer" inManagedObjectContext:context];

[customer setValue:name forKey:@"name"];

for (id contact in contacts) {
    ABRecordRef ref = (__bridge ABRecordRef)(contact);
    Contact *contact = [NSEntityDescription insertNewObjectForEntityForName:@"Contact" inManagedObjectContext:context];

    [contact setValue:(__bridge id)(ref) forKey:@"addressBookId"];
    [customer addContactObject:contact];
}

NSError *error;

if ([context save:&error]) { // <----------- ERROR
    // ...
}

私のコードでは、次のエラーが発生します:

-[__NSCFType encodeWithCoder:]: unrecognized selector sent to instance 0x9c840c0
*** -[NSKeyedArchiver dealloc]: warning: NSKeyedArchiver deallocated without having had -finishEncoding called on it.
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFType encodeWithCoder:]: unrecognized selector sent to instance 0x9c840c0'

任意の提案をいただければ幸いです。

4

1 に答える 1

3

問題は、addressBookId(コメントで述べたように)Contactエンティティの変換可能な属性として定義されていることです。ABRecordRefただし(コメントでも述べたように)、 CoreDataが保存方法を知っているものに実際に変換するためのカスタムコードはありません。カスタムトランスフォーマーがない場合、CoreDataは値を呼び出すことによって値を変換しようとencodeWithCoder:します。ただし、にABRecordRef準拠していないNSCodingため、これは失敗し、アプリがクラッシュします。

をCoreDataに保存する場合は、サブクラスABRecordRefを作成し、それをデータモデルで構成する必要があります。トランスフォーマーは、CoreDataが認識しているタイプの1つにNSValueTransformer変換する必要があります。ABRecordRef私はこれの詳細についてアドバイスするのに十分なアドレス帳APIを使っていませんが、AppleはNSValueTransformerかなりうまく文書化しています。

それが1対多の関係であるという事実は無関係です。問題は、ABRecordRef何らかの変換なしではデータストアに入ることができないということです。

于 2013-02-04T22:15:09.180 に答える