2016-01-06 60 views
0

我有一个包含两个实体'Parent'和'Child'的核心数据模型。 父母与孩子有多对多的关系,孩子与父母有一对一的关系。 我想防止在设置父项的情况下对子项中的父项关系进行更改。但是,应该允许删除孩子。不允许更改核心数据关系,但最终允许删除子项

孩子的的setParent看起来是这样的:

- (void)setParent:(Parent *)parent { 
    if (self.parent) return; 
    [self willChangeValueForKey:@"parent"]; 
    [self setPrimitiveValue:parent forKey:@"parent"]; 
    [self didChangeValueForKey:@"parent"]; 
    } 

现在,这阻止了父母的变化,一旦它的设置,但在同一时间,它会阻止删除的孩子,因为的setParent被重新在删除期间两次将父项设置为零。

第一次在删除期间调用setParent,self.isDeleted为true。所以我可以对这种情况做出反应。但setParent在删除期间再次被调用,这一次self.isDeleted为false,我不知道如何知道某人是否尝试编辑父关系或是否发生删除。

我与MagicalRecord 2.30和删除调用的工作是这样的:

[MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext)  { 

    [sut MR_inContext:localContext]; 
    [sut MR_deleteEntityInContext:localContext]; 
}]; 

我看了所有的地方找到有关期间删除那些二传手呼吁一些信息,但没有运气。 所以任何帮助,将不胜感激。

编辑 我把一些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> 
-------------------------------------------------------------------------- 
| 
+0

如果当'self.isDeleted'为true时将'parent'设置为'nil',则可以相当肯定地说,如果第二个调用不是删除的一部分,则无关紧要。除非你没有同步你的模型的更新,否则你被搞砸了。但是,无论如何你都被搞砸了。 – Avi

+0

@Avi - 谢谢。所以我让setter从delete pass调用,并期望parent被设置为nil。但事实并非如此。测试以这种方式工作,但是那里发生了什么? – donnerluetjen

+0

设置值后记录'self.parent'。如果你看,你会看到moc在第一个和第二个调用之间改变。我想第一个是第二个孩子的背景。在第三次调用之后,moc与第二次调用相同,并且'isDeleted == 1',你会发现'parent'是零。 – Avi

回答

0

这是我发现的。我已经改变了上面的代码来记录反向关系。

- (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 
-------------------------------------------------------------------------- 

所以,第一个和第三个时间设置器中删除名为,isDeleted是真实的。但在二传手的第二个电话isDeleted是错误的。 如果我在这一点测试反比关系,我发现它已被删除。这个测试对我来说已经足够了。它允许删除循环通过,同时允许运行setter,如果关系还没有被设置。

0

您可以设置parentnil如果isDeletedtrue,通过@Avi的建议。

相关问题