setPrimitiveValue:forKey:和一对多关系
时间:2020-03-06 14:40:48 来源:igfitidea点击:
当使用Apple来管理多对多关系时,Apple关于-setPrimitiveValue:forKey:
的文档含糊不清。
首先,他们说:
If you try to set a to-many relationship to a new NSMutableSet object, it will (eventually) fail.
最终?!那有什么意思?以后会在-[NSManagedObjectContext save:]
期间失败吗?当管理对象变成故障然后分页回去时?什么时候?我可以编写一个测试用例来按需一致地重新创建故障吗?
其次,提供示例代码以正确处理这种情况,他们写道:
first get the existing set using primitiveValueForKey: (ensure the method does not return nil)
如果/方法返回nil时应怎么办? assert()
并立即失败,因为这意味着整个对象图已损坏,保存会导致数据丢失? NSAssert()在其上作为对呼叫者的警告,但请按(静静地不执行任何操作)?
现在,在这种情况下,我只是直接分配所需的NS [Mutable] Set
,如下所示:
- (void)setChildren:(NSSet*)value_ { NSMutableSet *mutableRelationshipSet = [[[self primitiveValueForKey:@"children"] mutableCopy] autorelease]; if (mutableRelationshipSet) { [mutableRelationshipSet setSet:value_]; [self setPrimitiveValue:mutableRelationshipSet forKey:@"children"]; } else { [self setPrimitiveValue:value_ forKey:@"children"]; } }
那是错的吗?
解决方案
只需将-primitiveValueForKey:
的返回值更改为可变集,并相信其返回值将做正确的事情。
务必在操作周围使用-willChangeValueForKey:withSetMutation:usingObjects:和-didChangeValueForKey:withSetMutation:usingObjects:。我们没有在上面的代码中显示此内容。
- (void)setChildren:(NSSet *)value { [self willChangeValueForKey:@"children" withSetMutation:NSKeyValueSetSetMutation usingObjects:value]; NSMutableSet *primitiveValue = [self primitiveValueForKey:@"children"]; [primitiveValue setSet:value]; [self didChangeValueForKey:@"children" withSetMutation:NSKeyValueSetSetMutation usingObjects:value]; }
如果我们可以瞄准豹子,则不必为此担心。我们可以改为使用Core Data的内置属性支持:
#import <CoreData/CoreData.h> @interface Folder : NSManagedObject @property (readwrite, retain) NSSet *children; @end @implementation Folder @dynamic children; @end
核心数据不仅会为children
属性生成一个getter / setter对,而且还会为该可变集合访问器生成,因此我们可以在其上使用-mutableSetValueForKey:
并以最小的开销操作结果。