Objective-C:与CoreData的多对多关系

时间:2011-07-14 19:41:35

标签: iphone objective-c xcode core-data entity-relationship

我有一个iPhone应用程序有2个模型,分类和内容,它们有多对多的关系。

这是代码: 内容

@interface Content : NSManagedObject {
}

@property(readwrite, retain) NSString *type;
@property(readwrite, retain) NSString *mainText;
...
@property (copy) NSSet * categories;

@end

分类

@interface Category : NSManagedObject {

}
@property (nonatomic, retain) NSNumber * id;
@property (nonatomic, retain) NSNumber * active;
...
@property (copy) NSSet * contents;

@end

然后这个操作:

...
NSSet *tmp_set = [NSSet setWithArray:some_array_with_contents objectsAtIndexes:custom_indexes]];
cat.contents = tmp_set;
[[DataModel managedObjectContext] save:&error];
...

在最后一行,应用程序严重崩溃说:

-[__NSCFSet _isValidRelationshipDestination__]: unrecognized selector sent to instance 0x5c3bbc0
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFSet _isValidRelationshipDestination__]: unrecognized selector sent to instance 0x5c3bbc0'

1 个答案:

答案 0 :(得分:3)

您的关系属性不应使用副本。他们应该保留,例如:

@property (nonatomic, retain) NSSet* categories;

您不希望复制一组托管对象,因为您最终会在对象图中找到重复的对象。这将导致大问题。

但是,这不是当前的问题。直接的问题是某些东西导致用于托管对象的选择器被发送到集合本身。

这很可能是因为直接将复制的集合直接分配给关系而不是使用.m文件中定义的访问者方法之一。 @dynamic指令不会创建setCategories方法,因为这是一个托管对象,因此您无法获得正确的KVO通知,并且上下文无法正确更新。当它尝试保存时,它会将验证消息发送到设置对象而不是它包含的对象。

您应该在实现文件中使用addCategoryObjects:之类的方法。删除副本并使用这些方法可以解决问题。