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

Ios 执行删除规则时未调用的自定义多个关系访问器方法,ios,core-data,nsmanagedobject,Ios,Core Data,Nsmanagedobject,我有个问题我不明白 我有一个简单的核心数据模型,包括集合和CD。每个CD都可以添加到多个集合中,因此我添加了一个中间对象以实现这一点。(编辑:这是我的数据模型的简化。在集合中嵌套集合需要中间对象) 因此,将CD添加到收藏中时,其外观如下所示: (IM是中间对象) 我已经设置了删除规则,这样,如果用户删除了CD,IM对象将被级联删除,并且随着IM对象的删除,集合属性为nilled。这是我想要的。数据库中没有剩余内容 但奇怪的是,如果我重写custom to many relationship ac

我有个问题我不明白

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

因此,将CD添加到收藏中时,其外观如下所示: (IM是中间对象)

我已经设置了删除规则,这样,如果用户删除了CD,IM对象将被级联删除,并且随着IM对象的删除,集合属性为nilled。这是我想要的。数据库中没有剩余内容

但奇怪的是,如果我重写custom to many relationship accessor方法来从集合中删除IM(我假设会调用它),那么什么都不会发生

我正在使用苹果公司在其核心数据编程指南中提供的内容。

对于单个对象:

- (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,此处他们使用员工作为对多关系)

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

所以我的问题是:IM对象被级联删除,但是这些方法没有被使用。如何检测核心数据执行的删除操作

还有别的办法吗

我想知道这一点,因为我想在所有已更改的集合上设置一个“dirtyFlag”,以便可以更新这些对象的某些内容。(其他属性,此处不作解释)

(对象上的KVO将是无用的。我无法观察完整的数据库,对吗?。或者集合对象本身是否应该用于此属性?)


希望有人能帮助我

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


如果您想在每次删除时都设置脏标志,那么最好只注册
NSManagedObjectContextObjectsDidChangeNotification
通知。使用
NSDeletedObjectsKey
键从
userInfo
字典中取出已删除的对象。您可以在当时对其集合设置脏标志。

或者,您可以在IM managedObject子类中实现
-prepareForDeletion

-preparefordelection
在从managedObject上下文中删除之前,由managedObject上的核心数据自动调用

// 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];
    }
}
调用
-preparefordelection
时,所有关系仍然可用,您可以向所有包含的集合发送自定义
-willDeleteIntermediateObject:
消息,并将
self
作为参数传递

然后可以实现
-[Collection willdeleteemediateobject:
来检查它是否是它包含的最后一个IM对象,如果是,则使它从其managedObjectContext中删除自身

// 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];
    }
}

Thnx Aaron。我将调查这是否是我的解决方案。假设一个用户向收藏中添加了2张CD。并从该集合中删除1张CD。根据我的逻辑,可以删除带有1张CD的收藏。因此,我扫描数据库中的这些案例,并删除这些项目。这将再次触发通知。因此,我担心我最终会陷入这个循环,我想提高效率。所以,在while循环中:当存在“脏”集合时,扫描这些集合并删除只有一张CD的集合。然后再次启动while循环。我希望我能解释清楚。我会试试你的建议。Thanx!!!ps我不知道你所说的“使用获取的属性修改数据”是什么意思,除非你确定你确实存在可测量的低效率,否则我会避免花时间进行优化。关于获取的属性。感谢链接。不,我没有使用获取的属性。请注意,
self.intermediateObjects.count
给出了删除此实例之前集合中IM对象的数量。所以,如果你需要删除一个包含一个IM对象的集合,在删除这个oneWow之后,请将其与2进行比较!完全忽略了这个方法。苹果的核心数据编程指南(!!!)中没有提到这种方法。这就是我所需要的,所以我将把它标记为答案。谢谢是的,我知道。。。RTFM;)