【发布时间】:2016-01-06 18:27:28
【问题描述】:
我有一个包含两个实体的核心数据模型,“父”和“子”。 父母与孩子有一对多的关系,孩子与父母有一对一的关系。 一旦设置了父级,我想防止更改子级的父级关系。但是,应该允许删除孩子。
孩子的 setParent 长这样:
- (void)setParent:(Parent *)parent {
if (self.parent) return;
[self willChangeValueForKey:@"parent"];
[self setPrimitiveValue:parent forKey:@"parent"];
[self didChangeValueForKey:@"parent"];
}
现在,一旦设置了父级,这将阻止更改,但同时会阻止子级的删除,因为在删除期间 setParent 被重新访问两次以将父级设置为 nil。
在删除过程中第一次调用 setParent 时,self.isDeleted 为 true。所以我可以对这种情况做出反应。但是在删除过程中再次调用了 setParent,这一次 self.isDeleted 为假,我不知道如何知道是否有人试图编辑父关系或是否正在发生删除。
我正在使用 MagicalRecord 2.30,删除调用如下所示:
[MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) {
[sut MR_inContext:localContext];
[sut MR_deleteEntityInContext:localContext];
}];
我到处寻找有关删除期间那些 setter 调用的一些信息,但没有运气。 因此,我们将不胜感激。
编辑 我将一些 NSLogs 放入我的代码中以记录正在发生的事情。删除实际上适用于此代码,但我不知道所有这些调用是关于什么的。以下是相关代码:
- (BOOL) MR_deleteEntityInContext:(NSManagedObjectContext *)context {
NSLog(@"|");
NSLog(@"|");
NSLog(@"----------------------------------");
NSLog(@"| ***** starting delete... ***** |");
NSLog(@"----------------------------------");
NSLog(@"|");
NSLog(@"|");
return [super MR_deleteEntityInContext:context];
}
- (void)setParent:(Parent *)parent {
NSLog(@"|");
NSLog(@"--------------------------------------------------------------------------");
NSLog(@"setParent has been called with parameter <%p>", parent);
NSLog(@" self.parent is: %p", self.parent);
NSLog(@"self.isDeleted is: %hhd", self.isDeleted);
NSLog(@" self.moc: %@", self.managedObjectContext);
NSLog(@"--------------------------------------------------------------------------");
NSLog(@"|");
if (!self.isDeleted && self.parent) return;
[self willChangeValueForKey:@"parent"];
[self setPrimitiveValue:parent forKey:@"parent"];
[self didChangeValueForKey:@"parent"];
}
它产生以下输出:
----------------------------------
| ***** starting delete... ***** |
----------------------------------
|
|
|
--------------------------------------------------------------------------
setParent has been called with parameter <0x0>
self.parent is: 0x6080000a9cc0
self.isDeleted is: 1
self.moc: <NSManagedObjectContext: 0x6000001c05a0>
--------------------------------------------------------------------------
|
|
--------------------------------------------------------------------------
setParent has been called with parameter <0x0>
self.parent is: 0x6080000aa080
self.isDeleted is: 0
self.moc: <NSManagedObjectContext: 0x6080001c0a50>
--------------------------------------------------------------------------
|
|
--------------------------------------------------------------------------
setParent has been called with parameter <0x0>
self.parent is: 0x6080000aa080
self.isDeleted is: 1
self.moc: <NSManagedObjectContext: 0x6080001c0a50>
--------------------------------------------------------------------------
|
【问题讨论】:
-
如果在
self.isDeleted为真时将parent设置为nil,您可以相当确定第二次调用是否不是删除的一部分并不重要。除非你没有同步更新你的模型,否则你就完蛋了。但无论如何你都搞砸了。 -
@Avi - 谢谢。所以我让setter调用从delete pass,并期望父级设置为nil。但事实并非如此。测试是这样进行的,但是那里发生了什么???
-
设置值后记录
self.parent。如果你看,你会看到 moc 在第一次和第二次调用之间发生了变化。我猜第一个是第二个的子上下文。在第三次调用后,moc 与第二次相同,isDeleted == 1,你应该会发现parent为 nil。 -
@Avi - 你是对的。那么父母是零。在 delete 期间第二次调用 setter 并没有通过条件,因此没有设置任何东西,这似乎无关紧要。最后经过第三轮,child的parent属性为nil,parent的children属性为空。感谢您的帮助。
标签: objective-c core-data osx-yosemite magicalrecord