Objective-C:与 CoreData 的多对多关系
我有一个 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'
I've an iPhone applications with 2 models, Category and Content, which have a many-to-many relationship.
This is the code:
Content
@interface Content : NSManagedObject {
}
@property(readwrite, retain) NSString *type;
@property(readwrite, retain) NSString *mainText;
...
@property (copy) NSSet * categories;
@end
Category
@interface Category : NSManagedObject {
}
@property (nonatomic, retain) NSNumber * id;
@property (nonatomic, retain) NSNumber * active;
...
@property (copy) NSSet * contents;
@end
And then this operation:
...
NSSet *tmp_set = [NSSet setWithArray:some_array_with_contents objectsAtIndexes:custom_indexes]];
cat.contents = tmp_set;
[[DataModel managedObjectContext] save:&error];
...
On the last line, the app crashes badly saying:
-[__NSCFSet _isValidRelationshipDestination__]: unrecognized selector sent to instance 0x5c3bbc0
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFSet _isValidRelationshipDestination__]: unrecognized selector sent to instance 0x5c3bbc0'
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的关系属性不应使用副本。它们应该保留例如:
您不想复制一组托管对象,因为最终会在对象图中出现重复的对象。这会造成大问题。
然而,这并不是眼前的问题。迫在眉睫的问题是,某些原因导致将用于托管对象的选择器发送到集合本身。
这很可能是由于直接将复制的集分配给关系而不是使用
.m
文件中定义的访问器方法之一造成的。 @dynamic 指令不会创建 setCategories 方法,因为这是一个托管对象,因此您无法获得正确的 KVO 通知,并且上下文也无法正确更新。当它尝试保存时,它会将验证消息发送到设置的对象而不是它包含的对象。您应该在实现文件中具有类似
addCategoryObjects:
的方法。删除副本并使用这些方法应该可以解决问题。Your relationship properties should not use copy. They should retain e.g:
You don't want to copy a set of managed objects because you would end up with duplicate objects in the object graph. That is going to cause big problem.
However, that is not the immediate problem. The immediate problem is that something is causing a selector intended for a managed object to be sent to the set itself.
Most likely this is caused by directly assigning the copied set to the relationship directly instead of using one of the accessor methods defined in the
.m
file. The @dynamic directive will not create asetCategories
method because this is a managed object so you don't get proper KVO notifications and the context does not update properly. When it tries to save it sends validation messages to the set object instead of the objects it contains.You should have a method like
addCategoryObjects:
in the implementation file. Removing the copy and using those methods should resolve the problem.