为了确保我选择了正确的NSMergePolicy
,我很好奇设置为当前值的值是否能够在多个上下文中导致合并冲突。
具体来说,在我的情况下,我想确保修改后的标志会发生冲突并保存,如果设置在不合时宜的时刻。
示例:
//...
//on background thread, doing some work to an object because it's status was
//set to Status_Modified
[managedObjectContext performBlockAndWait:^{
object.status = Status_NotModified;
[managedObjectContext setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy];
[managedObjectContext save:&error];
}];
如果发生这种情况,在主线程上,状态设置为Status_Modified
并保存?对象状态是否保持为Status_Modified
?即将是“状态”#39;财产被认为是变化的,因此引起冲突,因此胜过我们的记忆变化(根据政策)?
答案 0 :(得分:2)
所以,我找不到任何体面的文档来回答这个问题,但我已经做了一些测试,似乎 属性被认为是改变的。这是我的怀疑,似乎同意will
/ didSetValueForKey:
包含的对键值设置的各种引用
我的测试:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSManagedObjectContext * uiCtx = [self contextForUIWork];
NSEntityDescription * entityDesc = [NSEntityDescription entityForName:@"Entity" inManagedObjectContext:uiCtx];
Entity * entity = [[Entity alloc] initWithEntity:entityDesc insertIntoManagedObjectContext:uiCtx];
entity.testproperty = @(1);
NSError * error = nil;
[uiCtx save:&error];
if (error)
{
assert(0);
}
NSManagedObjectID * objID = entity.objectID;
[self doStuffToObjectWithIDOnAnotherThreadAndAnotherContext:objID];
entity.testproperty = @(2);
[uiCtx setMergePolicy:NSErrorMergePolicy];
error = nil;
[uiCtx save:&error];
if (!error)
{
//We do not hit this! Success!
assert(0);
}
}
-(void)doStuffToObjectWithIDOnAnotherThreadAndAnotherContext:(NSManagedObjectID*)objID
{
dispatch_barrier_sync(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{
NSManagedObjectContext * bgCtx = [self contextForBackgroundWork];
Entity * bgEntity = (Entity*)[bgCtx objectWithID:objID];
[bgCtx performBlockAndWait:^{
//set to same value
bgEntity.testproperty = bgEntity.testproperty;
NSError * bgError = nil;
[bgCtx save:&bgError];
if (bgError)
{
assert(0);
}
}];
});
}
(上传完整测试代码:https://github.com/samskiter/CoreDataValueChangingTest)
来自文档的引用证实了这一点,远比仅有一些测试证明它适用于这个特定版本的iOS。