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:并以最小的开销操作结果。

