保存一对多关系CoreData
Posted
技术标签:
【中文标题】保存一对多关系CoreData【英文标题】:Saving one-to-many relationship CoreData 【发布时间】:2013-02-04 21:45:51 【问题描述】:我在 CoreData 中设置的关系有问题。它是一对多的,一个客户可以有多个联系人,这些联系人来自通讯录。
我的模型是这样的:
Customer <---->> Contact
Contact <-----> Customer
Contact.h
@class Customer;
@interface Contact : NSManagedObject
@property (nonatomic, retain) id addressBookId;
@property (nonatomic, retain) Customer *customer;
@end
客户.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'
任何建议将不胜感激。
【问题讨论】:
如何在您的数据模型中配置addressBookId
?您使用的是什么核心数据类型? Contact.m 是否有此属性的自定义设置器代码?
一种可能性是,您设置的 value
属性类型与数据模型上声明的属性类型不同
@TomHarrington Contact.m 没有任何自定义代码。而数据模型中的addressBookId
是Transformable
。
我不确定您是否可以将 ABRecordRef 桥接到这样的对象。 AddressBook 中没有表示联系人的对象。我建议创建自己的对象,或者简单地将 ABRecordRef id 保存为 CoreData 中的数字,并在需要时从 AB 读取它。保存到 CoreData 中的任何对象都需要支持编码,而且我不认为那个桥在工作。
【参考方案1】:
问题在于addressBookId
被定义为Contact
实体上的可转换属性(正如您在评论中提到的)。但是(正如您在评论中提到的那样)您没有任何自定义代码来实际将 ABRecordRef
转换为 Core Data 知道如何存储的东西。在没有自定义转换器的情况下,Core Data 将尝试通过在值上调用 encodeWithCoder:
来转换值。但是ABRecordRef
不符合NSCoding
,所以这会失败并且您的应用会崩溃。
如果您想将ABRecordRef
存储在Core Data 中,您需要创建一个NSValueTransformer
子类并在您的数据模型中配置它。您的转换器需要将 ABRecordRef
转换为 Core Data 知道的类型之一。我还没有充分使用地址簿 API 来提供有关此细节的建议,但 Apple 文档 NSValueTransformer
非常好。
它是一对多关系这一事实是无关紧要的;问题是ABRecordRef
不能在没有经过一些转换的情况下进入您的数据存储。
【讨论】:
以上是关于保存一对多关系CoreData的主要内容,如果未能解决你的问题,请参考以下文章
Core Data 使用多个上下文中的新对象从后台线程订购一对多关系保存