不允许更改核心数据关系,但最终允许删除 child
disallow change to core data relationship, but eventually allow for delete of the child
我有一个包含两个实体的核心数据模型,'Parent' 和 'Child'。
Parent 与 child 有 to-many 关系,child 与 parent 有 to-one 关系。
一旦 parent 已设置,我想防止 child 中的 parent 关系发生更改。但是,应该允许删除 child。
child 的集合Parent 看起来像这样:
- (void)setParent:(Parent *)parent {
if (self.parent) return;
[self willChangeValueForKey:@"parent"];
[self setPrimitiveValue:parent forKey:@"parent"];
[self didChangeValueForKey:@"parent"];
}
现在,这会阻止 parent 设置后的更改,但同时,它会阻止删除 child,因为设置 Parent 会被重新访问在删除期间两次将 parent 设置为 nil。
删除时第一次调用setParent,self.isDeleted为真。所以我可以对这种情况做出反应。但是在删除过程中又调用了 setParent ,这次 self.isDeleted 是假的,我不知道如何知道是否有人试图编辑 parent 关系或者是否删除了正在发生。
我正在使用 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>
--------------------------------------------------------------------------
|
如果 isDeleted
是 true
,您可以将 parent
设置为 nil
,正如@Avi 所建议的。
这是我的发现。我稍微更改了上面的代码以记录反向关系。
- (void)setParent:(Parent *)parent {
NSLog(@" ");
NSLog(@"--------------------------------------------------------------------------");
NSLog(@"| setParent has been called with parameter <%p>", parent);
NSLog(@"| self is: %p", self);
NSLog(@"| self.parent is: %p", self.parent);
NSLog(@"| parent.children contains: %p", [Parent MR_findFirstInContext:self.managedObjectContext].children.allObjects.firstObject);
NSLog(@"| self.isDeleted is: %hhd", self.isDeleted);
NSLog(@" ");
if (!self.isDeleted && self.parent) return;
if (self.isDeleted) [self setPrimitiveValue:nil forKey:@"parent"];
[self willChangeValueForKey:@"parent"];
[self setPrimitiveValue:parent forKey:@"parent"];
[self didChangeValueForKey:@"parent"];
NSLog(@"|- after setting the parent ...");
NSLog(@"|- self is: %p", self);
NSLog(@"|- self.parent is: %p", self.parent);
NSLog(@"|- parent.children contains: %p", [Parent MR_findFirstInContext:self.managedObjectContext].children.allObjects.firstObject);
NSLog(@"--------------------------------------------------------------------------");
}
当我删除子项时,会记录以下内容:
----------------------------------
| ***** starting delete... ***** |
----------------------------------
|
|
--------------------------------------------------------------------------
| setParent has been called with parameter <0x0>
| self is: 0x6000000a79e0
| self.parent is: 0x6000000a7a40
| parent.children contains: 0x6000000a79e0
| self.isDeleted is: 1
|- after setting the parent ...
|- self is: 0x6000000a79e0
|- self.parent is: 0x0
|- parent.children contains: 0x6000000a79e0
--------------------------------------------------------------------------
--------------------------------------------------------------------------
| setParent has been called with parameter <0x0>
| self is: 0x6080000a8100
| self.parent is: 0x6080000a8160
| parent.children contains: 0x0
| self.isDeleted is: 0
--------------------------------------------------------------------------
| setParent has been called with parameter <0x0>
| self is: 0x6080000a8100
| self.parent is: 0x6080000a8160
| parent.children contains: 0x0
| self.isDeleted is: 1
|- after setting the parent ...
|- self is: 0x6080000a8100
|- self.parent is: 0x0
|- parent.children contains: 0x0
--------------------------------------------------------------------------
因此,在删除过程中第一次和第三次调用 setter 时,isDeleted
为真。但是在 setter 的第二次调用中 isDeleted
是错误的。
如果我此时测试反向关系,我会发现它已经被删除了。那个测试对我来说已经足够好了。它允许删除循环通过,同时允许运行如果关系根本没有设置setter
我有一个包含两个实体的核心数据模型,'Parent' 和 'Child'。 Parent 与 child 有 to-many 关系,child 与 parent 有 to-one 关系。 一旦 parent 已设置,我想防止 child 中的 parent 关系发生更改。但是,应该允许删除 child。
child 的集合Parent 看起来像这样:
- (void)setParent:(Parent *)parent {
if (self.parent) return;
[self willChangeValueForKey:@"parent"];
[self setPrimitiveValue:parent forKey:@"parent"];
[self didChangeValueForKey:@"parent"];
}
现在,这会阻止 parent 设置后的更改,但同时,它会阻止删除 child,因为设置 Parent 会被重新访问在删除期间两次将 parent 设置为 nil。
删除时第一次调用setParent,self.isDeleted为真。所以我可以对这种情况做出反应。但是在删除过程中又调用了 setParent ,这次 self.isDeleted 是假的,我不知道如何知道是否有人试图编辑 parent 关系或者是否删除了正在发生。
我正在使用 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>
--------------------------------------------------------------------------
|
如果 isDeleted
是 true
,您可以将 parent
设置为 nil
,正如@Avi 所建议的。
这是我的发现。我稍微更改了上面的代码以记录反向关系。
- (void)setParent:(Parent *)parent {
NSLog(@" ");
NSLog(@"--------------------------------------------------------------------------");
NSLog(@"| setParent has been called with parameter <%p>", parent);
NSLog(@"| self is: %p", self);
NSLog(@"| self.parent is: %p", self.parent);
NSLog(@"| parent.children contains: %p", [Parent MR_findFirstInContext:self.managedObjectContext].children.allObjects.firstObject);
NSLog(@"| self.isDeleted is: %hhd", self.isDeleted);
NSLog(@" ");
if (!self.isDeleted && self.parent) return;
if (self.isDeleted) [self setPrimitiveValue:nil forKey:@"parent"];
[self willChangeValueForKey:@"parent"];
[self setPrimitiveValue:parent forKey:@"parent"];
[self didChangeValueForKey:@"parent"];
NSLog(@"|- after setting the parent ...");
NSLog(@"|- self is: %p", self);
NSLog(@"|- self.parent is: %p", self.parent);
NSLog(@"|- parent.children contains: %p", [Parent MR_findFirstInContext:self.managedObjectContext].children.allObjects.firstObject);
NSLog(@"--------------------------------------------------------------------------");
}
当我删除子项时,会记录以下内容:
----------------------------------
| ***** starting delete... ***** |
----------------------------------
|
|
--------------------------------------------------------------------------
| setParent has been called with parameter <0x0>
| self is: 0x6000000a79e0
| self.parent is: 0x6000000a7a40
| parent.children contains: 0x6000000a79e0
| self.isDeleted is: 1
|- after setting the parent ...
|- self is: 0x6000000a79e0
|- self.parent is: 0x0
|- parent.children contains: 0x6000000a79e0
--------------------------------------------------------------------------
--------------------------------------------------------------------------
| setParent has been called with parameter <0x0>
| self is: 0x6080000a8100
| self.parent is: 0x6080000a8160
| parent.children contains: 0x0
| self.isDeleted is: 0
--------------------------------------------------------------------------
| setParent has been called with parameter <0x0>
| self is: 0x6080000a8100
| self.parent is: 0x6080000a8160
| parent.children contains: 0x0
| self.isDeleted is: 1
|- after setting the parent ...
|- self is: 0x6080000a8100
|- self.parent is: 0x0
|- parent.children contains: 0x0
--------------------------------------------------------------------------
因此,在删除过程中第一次和第三次调用 setter 时,isDeleted
为真。但是在 setter 的第二次调用中 isDeleted
是错误的。
如果我此时测试反向关系,我会发现它已经被删除了。那个测试对我来说已经足够好了。它允许删除循环通过,同时允许运行如果关系根本没有设置setter