setPrimitiveValue:forKey:和to-many关系

时间:2008-09-24 18:23:43

标签: objective-c cocoa core-data

Apple的documentation on -setPrimitiveValue:forKey:在使用它来管理多人关系时,在两个方面含糊不清。

首先他们说:

  

如果您尝试设置与新NSMutableSet对象的多对多关系,它将(最终)失败。

最终?! 这甚至意味着什么?它会在-[NSManagedObjectContext save:]期间失败吗?当托管对象变成故障然后再回来时?什么时候?我是否可以编写一个测试用例来始终按需重新创建失败?

其次,提供示例代码以正确处理这种情况,他们写道:

  

首先使用primitiveValueForKey:获取现有集合(确保方法不返回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"];
    }
}

这是错的吗?

1 个答案:

答案 0 :(得分:6)

只需将-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];
}

如果你可以瞄准Leopard,你不必担心这个;您可以使用Core Data的内置属性支持:

#import <CoreData/CoreData.h>

@interface Folder : NSManagedObject
@property (readwrite, retain) NSSet *children;
@end

@implementation Folder
@dynamic children;
@end

核心数据不仅会生成children属性的getter / setter对,还会生成可变集访问器,因此您可以在其上使用-mutableSetValueForKey:并以最少的值操作结果开销。