在iPhone核心数据中使用级联删除规则和validateForDelete对一对多关系

Tre*_*ham 4 iphone cocoa-touch core-data objective-c

前言:

我将两个实体定义为一对多关系:<< -------> B. B.与A的关系称为myAs,是与Nullify作为删除规则的多对多关系.从A到B的反比关系是与Cascade作为删除规则的一对一关系.

我在B类上实现了validateForDelete,如下所示:

- (BOOL)validateForDelete:(NSError **)error {
    [super validateForDelete:error];
    BOOL validDelete = FALSE;

    if ([self.myAs count] == 0) {
        validDelete = TRUE;
    }

    return validDelete;
}
Run Code Online (Sandbox Code Playgroud)

这样做的目的是只有在与它的关系中没有更多A对象时才删除对象B(但如果在与它的关系中不再有任何A对象,则总是删除B对象).如果我在保存之前手动检查此验证,则validateForDelete按预期工作:删除B对象:

if ([b validateForDelete:NULL]) {
    //delete b object...
    [context save:&error];
    ...
}
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是从A对象删除级联删除B对象.用户无法直接访问B对象 - 它们是通过A对象创建和删除的.因此,当没有更多A对象与之关联时,我的规则要删除B对象必须从A对象强制执行 - 因此删除时级联.

问题是,当我删除A对象时,由于级联,在B对象上调用validateForDelete.我收到一个已解决的错误:未解决的错误(null),(null)因为我没有手动调用validateForDelete.

问题(S):

如何以编程方式从级联删除访问validateForDelete调用,以便我可以传入错误变量和/或处理FFAL的validateForDelete结果?

如果上述情况不可能,我该如何处理这个用例?还有另一种更实用的方法来实现这一目标吗?

提前致谢.

Mar*_*rra 12

首先,你对super的调用忽略了它的响应,它没有对super的响应起作用.这通常是一个坏主意.

其次,当你对validateForDelete说NO时会抛出异常,因为删除规则无法完成; 在这种情况下级联删除.简而言之,验证方法不是尝试处理这种情况的正确位置.

要处理这种情况,您应该覆盖-prepareForDeletionA类中的方法,并让它查看适合该情况的任何B并根据需要删除它们.您还需要将删除规则更改为nullify而不是cascade.我会按如下方式实现它:

- (void) prepareForDeletion
{
  [super prepareForDeletion];
  if (![self myB]) return; //I don't have a B
  if ([[[self myB] myAs] count] > 1) return; //Has more relationships
  [[self managedObjectContext] deleteObject:[self myB]];
}
Run Code Online (Sandbox Code Playgroud)

这将检查您是否有B,如果B有多个关系,如果没有,则将其添加到队列中以进行删除.否则,它将允许Core Data取消关系.