禁止更改核心数据关系,但最终允许删除子级

时间:2016-01-06 18:27:28

标签: objective-c core-data osx-yosemite magicalrecord

我有一个核心数据模型,包含两个实体,'Parent'和'Child'。 父母与孩子有多对多的关系,孩子与父母有一对一的关系。 我希望在设置父级之后阻止更改子级中的父关系。但是,应该允许删除孩子。

孩子的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为false,我不知道如何知道是否有人试图编辑父关系或者是否正在进行删除。

我正在使用MagicalRecord 2.30,删除调用如下所示:

[MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext)      {

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

我一直在寻找有关删除期间这些setter调用的一些信息,但没有运气。 所以任何帮助都会受到赞赏。

修改 我把一些NSLog放到我的代码中,文件正在发生。删除实际上适用于此代码,但我不知道所有这些调用是关于什么的。以下是相关代码:

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

2 个答案:

答案 0 :(得分:0)

根据@Avi的建议,// JavaScript does not have an Array for range constructor. // function range( start, count ) { // (Int,Int) -> Array of Int var arr = []; for (var i=0; i<count; i++ ) { arr[i]= start+i; } return arr; } return Rx.Observable
 .range(0,ev.changedTouches.length) // (start, count) .select( function (i) { return touchDragObs( ev, i );
 });
 parent时,您可以将nil设置为isDeleted

答案 1 :(得分: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
--------------------------------------------------------------------------

因此,在删除期间第一次和第三次调用setter时,isDeleted为真。但是在第二次调用setter isDeleted时是错误的。 如果我此时测试反向关系,我发现它已经被删除了。那个测试对我来说已经足够了。它允许删除周期通过,同时如果根本没有设置关系,则允许运行setter。