2013-01-02 81 views
0

UPDATE:下面马丁R已经提供了一个非常明确的(和简洁!)回答almosts回答我的问题。我想我应该改为:问题核心数据删除的过程中发现NSManagedObject的一对一关系

你可以想一下,为什么在调用prepareForDeletion时,获取连接到另一个NSManagedObject的NSManagedObjects不起作用,因为这样的对象与被删除的对象是一对一连接的?

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


是否有任何技巧在核心数据中删除对象的子对象时它是一对一的关系?

我有一个相当复杂的核心数据模型,其中删除单个N​​SManagedObject也应通过prepareForDeletion删除其子NSManagedObjects。在删除之前立即运行一系列调试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”具有一对一的关系。

+0

一个更简单的解决方案可能是将关系的“删除规则”从* MainObject *设置为* ChildX *设置为“Cascade”。然后删除* MainObject *实体的对象会自动删除* ChildX *实体的所有相关对象。 –

+0

由于@MartinR建议你应该使用删除规则。你使用什么类型的规则?看看这里https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdRelationships.html –

+0

从* ChildX *到* MainObject *设置为nullify。这意味着:如果一个孩子被删除,对父母不做任何事情。 –

回答

1

所以我终于得到了IRC为我工作!和#iphonedev渠道上的帮助人员提供了以下洞察:

•(与Martin R说的一样)我应该忍受构建Core Data模型的可视界面,并使用提供的“Delete Rule”下拉菜单创建我的删除逻辑。 (在“Utilities”右侧窗格中,第三个看起来像奶酪楔子的标签)。“Cascade”和“Nullify”是最有用的值。

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

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

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

+0

有没有办法“接受”两个答案?马丁R的答案是66%的解决方案。 –

+0

不,不幸的是:-)根据常见问题,人们应该接受“最有帮助”的答案。如果你接受你自己的答案(我没有问题)。 –

1

如果您正确设置关系的“删除规则”,删除“依赖”对象可以由核心数据自动处理。在这种情况下,您可以ChildX为“瀑布”,从的反比关系

  • 删除规则ChildX设置

    • MainObject关系删除规则MainObject来“抵消” 。

    这意味着

    • 如果MainObject被删除时,相关ChildX对象也被删除。
    • 如果ChildX对象被删除,则将来自相关联的MainObject的关系值设置为NULL。
  • +0

    AH好吧。我没有意识到删除规则是单向的。 –