0

更新:下面的 Martin R 提供了一个非常清晰(简洁!)的答案,几乎可以回答我的问题。我想我应该改写:

prepareForDeletion考虑到这些对象与被删除的对象一对一地连接,您能想到为什么在调用时无法获取连接到另一个 NSManagedObject 的 NSManagedObjects 的任何原因吗?

我需要能够调用prepareForDeletion,以便在决定是否应该删除对象的子对象之前运行一些实体检查。


当它是一对一关系时,在Core Data中删除对象的子对象有什么技巧吗?

我有一个相当复杂的核心数据模型,其中删除单个 NSManagedObject 还应该通过prepareForDeletion. 在删除之前立即运行一系列调试 NSLog 语句表明所有关系都已正确设置。然而,当实际尝试删除对象时,似乎许多(尽管不是全部)这些关系已经丢失,因为尝试通过 NSFetchRequest 获取这些对象中的一些(但同样,不是全部)返回空数组。

我似乎无法弄清楚我如何获取找到的对象与未找到的对象之间的任何区别,除了那些找到的对象是反向的多对关系,而那些找不到的对象是一对多的关系-一种关系:-/

要删除“主”对象,我只需调用[managedObjectContext deleteObject:mainObject];,并在主对象的私有 API 中覆盖prepareForDeletion如下:

- (void)prepareForDeletion
{
//    [super prepareForDeletion]; // commented but uncommenting doesn't change results
    [MyDataManager deleteChildOneForMainObject:self];
    [MyDataManager deleteChildrenTwoForMainObject:self];
    [MyDataManager deleteChildrenThreeForMainObject:self];
}

哪里MyDataManager是一个只包含类方法的自定义 NSObject。MyDataManager 然后通过类似于以下内容在托管对象上下文中搜索相应的 NSManagedObjects:

- (BOOL)deleteChildOneForMainObject:(MainObject *)mainObject
{
    NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"ChildOne" inManagedObjectContext:managedObjectContext];
    [fetch setEntity:entity];
    [fetch setPredicate:[NSPredicate predicateWithFormat:@"(mainObject == %@)", mainObject]];
    NSError *error;
    NSArray *childOnesToDelete = [managedObjectContext executeFetchRequest:fetch error:&error];
    if (childOnesToDelete.count > 1)
    {
        NSLog(@"[WARNING] More than one ChildOne for mainObject found; deleting all");
    }
    NSLog(@"[TEST] Deleting %i ChildOnes", childOnesToDelete.count);
    for (ChildOne *childOne in childOnesToDelete)
    {
        [managedObjectContext deleteObject:childOne];
    }
    if ([managedObjectContext save:&error]) return YES;
    else NSLog(@"[WARNING] Save error for function [deleteChildOneForMainObject:]");
    return NO;
}

同样,每个“MainObject”类型的 NSManagedObject 与“ChildOne”具有一对一关系,与“ChildTwo”和“ChildThree”具有一对多关系。“Child One”、“ChildTwo”和“ChildThree”都与“MainObject”具有一对一的关系。

4

2 回答 2

1

如果您正确设置关系的“删除规则”,Core Data 可以自动处理删除“依赖”对象。在这种情况下,您可以设置

  • 删除从MainObjectChildX到 "Cascade" 的关系规则,
  • 删除从ChildXMainObject到“Nullify”的反向关系规则。

这意味着

  • 如果MainObject被删除,则相关的ChildX对象也会被删除。
  • 如果删除ChildX对象,则相关MainObject的关系值设置为 NULL。
于 2013-01-02T21:29:12.897 回答
1

所以我终于让 IRC 为我工作了!#iphonedev 频道上的一位乐于助人的人提供了以下见解:

• (就像Martin R 所说)我应该忍受构建我的核心数据模型的可视化界面,并使用提供的“删除规则”下拉菜单来创建我的删除逻辑。(在“实用程序”右侧窗格中,第三个选项卡看起来像一块奶酪。)“级联”和“无效”是最有用的值。

• “删除规则”是单向的并且对每个关系都是唯一的,因此您有相当程度的控制权。

• 无需获取与提供的 NSManagedObject 具有一对一关系的 NSManagedObject,只需使用该属性即可。使用 fetch 作为“保护”机制是愚蠢和不必要的,因为根据定义,这种关系是一对一的。所以如果我有YingandYang对象,我应该只执行[managedObjectContext deleteObject:ying.yang]or [managedObjectContext deleteObject:yang.ying]

根据 Martin R 的回答,最终prepareForDeletion仅与级联删除有关。

于 2013-01-03T06:57:32.190 回答