iPhone Core Data 关系故障
Posted
技术标签:
【中文标题】iPhone Core Data 关系故障【英文标题】:iPhone Core Data relationship fault 【发布时间】:2010-06-26 13:01:43 【问题描述】:我正在构建一个核心数据 iphone 应用程序,但在检索一对多关系数据时遇到了问题。请耐心等待我解释。
我使用数据模型设计器设置了一个名为“Item”的实体,其中包含许多名为“Comment”的实体。然后我检索多个实体并将它们显示在UITableView
中。我像这样获取这些实体(在viewDidLoad
方法中):
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Items" inManagedObjectContext:self.managedObjectContext];
[request setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(Item_to_Areas.Name LIKE %@)",[areaManagedObject valueForKey:@"Name"]];
[request setPredicate:predicate];
[request setRelationshipKeyPathsForPrefetching:[NSArray arrayWithObject:@"Item_to_item_comments"]];
NSLog(@"Results: %@", [mutableItemsFetchResults description]);
mutableItemsFetchResults = [[managedObjectContext executeFetchRequest:request error:nil] mutableCopy];
[request release];
当用户点击一行时,我选择特定的实体,在其 init 方法中将其传递给新的表视图控制器,并将新的视图控制器推送到堆栈:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
NSLog(@"itemObject: %@", [mutableItemsFetchResults objectAtIndex:indexPath.row]);
InspectionItemCommentsViewController *itemCommentsViewController = [[InspectionItemCommentsViewController alloc]
initWithManagedObjectContext:self.managedObjectContext
itemObject:[mutableItemsFetchResults objectAtIndex:indexPath.row]];
itemCommentsViewController.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:itemCommentsViewController animated:YES];
[itemCommentsViewController release];
在第一个块中,NSLog 输出显示“Item_to_item_cmets”关系实体已被检索,但在第二个块中,即使我调用了 [request setRelationshipKeyPathsForPrefetching:[NSArray arrayWithObject:@"Item_to_item_cmets"]],它也没有。
这是第一个 NSLog 输出的一部分:
Results: (
"<NSManagedObject: 0xb356b70> (entity: Items; id: 0xb34fe60 <x-coredata://E43A90B5-AF0E- 4394-B4A7-5EFE74E181F8/Items/p1> ; data: \n Clean = nil;\n Description = \"\";\n ItemToInformation = \"<relationship fault: 0x5e1ef00 'ItemToInformation'>\";\n \"Item_to_Areas\" = \"0xb33fd30 <x-coredata://E43A90B5-AF0E-4394-B4A7-5EFE74E181F8/Areas/p1>\";\n \"Item_to_item_comments\" = \"<relationship fault: 0x5e1d300 'Item_to_item_comments'>\";\n Keys = nil;\n Name = Other;\n \"Tenant_agrees\" = nil;\n Undamaged = nil;\n Working = nil;\n)",
"<NSManagedObject: 0xb35a930> (entity: Items; id: 0xb32acc0 <x-coredata://E43A90B5-AF0E-4394-B4A7-5EFE74E181F8/Items/p2> ; data: \n Clean = nil;\n Description = \"\";\n ItemToInformation = \"<relationship fault: 0x790de40 'ItemToInformation'>\";\n \"Item_to_Areas\" = \"0xb33fd30 <x-coredata://E43A90B5-AF0E-4394-B4A7-5EFE74E181F8/Areas/p1>\";\n \"Item_to_item_comments\" = (\n \"0xb35bcb0 <x-coredata://E43A90B5-AF0E-4394-B4A7-5EFE74E181F8/Item_Comments/p13>\",\n \"0xb35bcd0 <x-coredata://E43A90B5-AF0E-4394-B4A7-5EFE74E181F8/Item_Comments/p37>\",\n \"0xb35bca0 <x-coredata://E43A90B5-AF0E-4394-B4A7-5EFE74E181F8/Item_Comments/p5>\",\n \"0xb35bcc0 <x-coredata://E43A90B5-AF0E-4394-B4A7-5EFE74E181F8/Item_Comments/p26>\"\n );\n Keys = nil;\n Name = Lights;\n \"Tenant_agrees\" = nil;\n Undamaged = nil;\n Working = nil;\n)",
您可以看到已获取 Items 实体,包括 Item_to_item_comments
。这是第二个 NSLog:
itemObject: <NSManagedObject: 0xe20af50> (entity: Items; id: 0xe209fc0 <x- coredata://E43A90B5-AF0E-4394-B4A7-5EFE74E181F8/Items/p2> ; data:
Clean = nil;
Description = "";
ItemToInformation = "<relationship fault: 0xe302e40 'ItemToInformation'>";
"Item_to_Areas" = "0xe500b90 <x-coredata://E43A90B5-AF0E-4394-B4A7-5EFE74E181F8/Areas/p1>";
"Item_to_item_comments" = "<relationship fault: 0xe302e60 'Item_to_item_comments'>";
Keys = nil;
Name = Lights;
"Tenant_agrees" = nil;
Undamaged = nil;
Working = nil;
)
现在,Item_to_item_comments
是错误的。同样,在推送的视图控制器中,传递了 Items 实体,但没有传递 Item_to_item_comments
。
我想我遗漏了一些明显的东西,但是在这个问题上花费了一天之后,我无法弄清楚。
任何帮助将不胜感激。
彼得
【问题讨论】:
【参考方案1】:“错误”并不意味着错误,它只是意味着返回的对象是没有读入其属性的“幽灵”。对于关系的另一方来说,出现错误是正常的,因为你没有什么fetch 通过其关系引发对象创建的不受控制的级联。
当您访问故障的一个属性时,它将作为一个功能齐全的对象进入故障。
编辑:
来自评论:
问题是我在请求 这种关系通过NSLog,但我 仍然无法得到关系 实体。
不,你不是。您只需请求Items
实体本身,然后记录它们。正如预期的那样,他们正在为他们的关系返回错误。只有当您向每个人询问关系另一端的实际对象时,您才能保证看到一个对象而不是错误。
这就是你需要强制关系中的对象的错误:
NSLog(@"itemObject.Item_to_item_comments: %@", [mutableItemsFetchResults objectAtIndex:indexPath.row].Item_to_item_comments.someAttribute]);
您的另一个问题是您正在比较两个单独提取的结果。这个:
NSLog(@"Results: %@", [mutableItemsFetchResults description]);
mutableItemsFetchResults = [[managedObjectContext executeFetchRequest:request error:nil] mutableCopy];
...记录mutableItemsFetchResults
在提取发生之前。下一个 NSLog(大概)记录获取后的结果。这意味着您可能正在查看处于两种不同故障状态的两组不同对象。
您可能还会遇到问题,因为mutableItemsFetchResults
显然是一个属性,但您没有使用self.mutableItemsFetchResults
表示法来确保它被正确保留。另外,我认为您不需要mutableCopy
。
【讨论】:
我了解 Core Data 在被请求之前不会加载“对多”关系。问题是我通过 NSLog 请求这样的关系,但我仍然无法获取关系实体。我希望我对这个问题的解释是充分的。再次感谢。 谢谢,帮助很大,说得通。新手错误!以上是关于iPhone Core Data 关系故障的主要内容,如果未能解决你的问题,请参考以下文章
在 Core Data 中获取数据时的 performBackgroundTask 故障错误
从内存存储中删除 Core Data 对象会将它们变成故障,但不会擦除它们