【发布时间】:2013-01-02 20:39:17
【问题描述】:
更新:下面的 Martin R 提供了一个非常清晰(简洁!)的答案,几乎回答了我的问题。我想我应该改写:
在调用prepareForDeletion 时,如果这些对象与被删除的对象一对一地连接,你能想到为什么无法获取连接到另一个 NSManagedObject 的 NSManagedObject 的任何原因吗?
我需要能够调用prepareForDeletion,以便在决定是否应该删除对象的子对象之前运行一些实体检查。
在Core Data中删除对象的子对象是一对一关系时,有什么技巧吗?
我有一个相当复杂的核心数据模型,其中删除单个 NSManagedObject 还应该通过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”具有一对一的关系。
【问题讨论】:
-
一个更简单的解决方案可能是将关系的“删除规则”设置为从 MainObject 到 ChildX 到“Cascade”。那么删除 MainObject 实体的一个对象会自动删除 ChildX 实体的所有相关对象。
-
正如@MartinR 建议的那样,您应该使用删除规则。你使用什么类型的规则?看看这里developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/…
-
从 ChildX 到 MainObject 设置无效。这意味着:如果一个孩子被删除,对父母不做任何事情。
-
“级联”是否深入 1 级?如果其他对象也在层次结构中,我将如何防止它们被删除?例如,ChildTwo 也一对一地绑定到对象 HouseOne,但我不希望在通过 MainObject 删除 ChildTwo 时删除 HouseOne。
-
@KenHaggerty:这取决于从 ChildTwo 到 HouseOne 的删除规则,因此您可以单独控制。
标签: objective-c cocoa cocoa-touch core-data