简体   繁体   中英

Objective-C: Many to many relationship with CoreData

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'

Your relationship properties should not use copy. They should retain eg:

@property (nonatomic, retain) NSSet* categories;

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 a setCategories 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM