自定义多对多关系访问器执行删除规则时未调用的方法

时间:2014-11-14 01:17:15

标签: ios core-data nsmanagedobject

我有一个问题,我不明白..

我有一个简单的核心数据模型,包含Collection和CD。每张CD都可以添加到多个集合中,所以我添加了一个中间对象来实现这一点。 (编辑:这是我的DataModel的简化。在集合中嵌套集合需要中间对象)

因此,当CD添加到Collection时,它看起来像这样: (IM是中间对象)

|==========|         |==========|         |==========|
|          |         |          |         |          |
|Collection|=========|   IM     |=========|    CD    |
|          |         |          |         |          |
|==========|         |==========|         |==========|

我已经设置了删除规则,以便在用户删除CD时,IM对象被级联删除,并且删除IM对象时,会占用集合属性。这表现得像我想要的那样。数据库中没有剩菜。

但奇怪的是,如果我覆盖自定义多对多关系访问器方法以从集合中移除IM(我假设将被调用),则不会发生任何事情。

我正在使用Apple在其核心数据编程指南中提供的内容。 the link

对于单个对象:

- (void)removeEmployeesObject:(Employee *)value
  {
      NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
      [self willChangeValueForKey:@"employees"
            withSetMutation:NSKeyValueMinusSetMutation
            usingObjects:changedObjects];
      [[self primitiveEmployees] removeObject:value];
      [self didChangeValueForKey:@"employees"
            withSetMutation:NSKeyValueMinusSetMutation
            usingObjects:changedObjects];
}

用于删除多个对象:

- (void)removeEmployees:(NSSet *)value
  {
      [self willChangeValueForKey:@"employees"
            withSetMutation:NSKeyValueMinusSetMutation
            usingObjects:value];
      [[self primitiveEmployees] minusSet:value];
      [self didChangeValueForKey:@"employees"
            withSetMutation:NSKeyValueMinusSetMutation
            usingObjects:value];
}

(取自pdf,他们在这里使用Employee作为多对多关系)

但是执行删除规则时不会调用这些方法!

所以我的问题:IM对象被级联删除,但不使用这些方法。如何检测Core Data执行的删除操作?

还有其他办法吗?

我想知道这个,因为我想在已经更改的所有Collection上设置一个“dirtyFlag”,所以我可以为这些对象更新一些东西。 (其他属性,这里不解释)

(对象上的KVO将毫无用处。我不能去观察完整的数据库,可以吗?或者Collection对象KVO本身应该用于此属性吗?)

希望有人可以帮助我!

2 个答案:

答案 0 :(得分:3)

或者,您可以在IM managedObject子类中实现-prepareForDeletion 在托管对象从托管对象的托管对象中删除之前,核心数据会自动调用-prepareForDeletion

调用-prepareForDeletion后,所有关系仍然可用,您可以向所有包含的集合发送自定义-willDeleteIntermediateObject:消息,并将self作为参数传递。

然后,您可以实现-[Collection willDeleteIntermediateObject:]来检查它是否是它包含的最后一个IM对象,如果是,请将其从托管对象中删除。

// IM.m
- (void)prepareForDeletion {
    [super prepareForDeletion];

    for (Collection *collection in self.collections) {
        [collection willDeleteIntermediateObject:self];
    }
}

// Collection.m
- (void)willDeleteIntermediateObject:(IM *)im {
    if (self.intermediateObjects.count == 1 && [self.intermediateObjects.containsObject:im]) {
        [self.managedObjectContext deleteObject:self];
    }
}

答案 1 :(得分:1)

您是否使用获取的属性修改数据?在这种情况下,不会调用可变集合访问器方法。

如果要在字面上每次删除时设置脏标志,那么简单地注册NSManagedObjectContextObjectsDidChangeNotification通知可能是更好的模式。使用NSDeletedObjectsKey键从userInfo字典中删除已删除的对象。您可以在那时在其集合上设置脏标志。