保存一对多关系CoreData

时间:2013-02-04 21:45:51

标签: ios core-data one-to-many nsmanagedobject

我在CoreData中设置的关系遇到了麻烦。它的一对多,客户可以有很多联系,这些联系人来自地址簿。

我的模型看起来像这样:

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'

任何建议都将不胜感激。

1 个答案:

答案 0 :(得分:3)

问题在于addressBookId(在评论中提到)被定义为Contact实体上的可转换属性。但是(正如您在评论中也提到的那样),您没有任何自定义代码可以将ABRecordRef实际转换为Core Data知道如何存储的内容。如果没有自定义转换器,Core Data将尝试通过调用值encodeWithCoder:来转换值。但ABRecordRef不符合NSCoding,因此失败并且您的应用崩溃了。

如果要将ABRecordRef存储在Core Data中,则需要创建一个NSValueTransformer子类并在数据模型中对其进行配置。您的变换器需要将ABRecordRef转换为Core Data知道的类型之一。我没有使用地址簿API足以提供有关详细信息的建议,但Apple文档NSValueTransformer非常好。

这是一对多关系这一事实无关紧要;问题是ABRecordRef无法在没有转换的情况下进入您的数据存储。