iPhone核心数据关系故障
我正在构建一个核心数据 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_comments”关系实体,但在第二个块中,即使我调用了 [request setRelationshipKeyPathsForPrefetching:[NSArray arrayWithObject:@"Item_to_item_comments] 也没有检索到“Item_to_item_comments”关系实体”]]。
以下是第一个 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
。
我认为我错过了一些明显的东西,但在这个问题上花了一天时间后,我无法弄清楚。
任何帮助将不胜感激。
彼得
I am building a core data iphone app, and having trouble with retrieving one-many relationship data. Please bear with me while I explain.
I have used the data model designer to setup an entity called "Item" that contains many entities called "Comment". I then retrieve multiple entities and display them in a UITableView
. I fetch these entities like this (in the viewDidLoad
method):
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];
When the user taps on a row, I select the particular entiny, pass it to a new table view controller in its init method, and push the new view controller to the stack:
- (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];
}
In the first block the NSLog output shows that the "Item_to_item_comments" relationship entities were retrieved, but in the second, that it wasn't even though I invoked [request setRelationshipKeyPathsForPrefetching:[NSArray arrayWithObject:@"Item_to_item_comments"]].
Here is part of the first NSLog output:
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})",
You can see that the Items entities are fetched, including Item_to_item_comments
. Here's the second 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;
})
Now, Item_to_item_comments
is fault. Similarly, in the pushed view controller, the Items entity is passed, but Item_to_item_comments
is not.
I think I am missing something obvious, but after a day spend on this problem, I can't figure it out.
Any help would be appreciated.
Peter
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
“故障”并不意味着错误,它只是意味着返回的对象是一个“幽灵”,没有读入其属性。关系的另一方出现故障是正常的,因为您不知道要设置什么通过其关系进行不受控制的对象创建级联。
当您访问故障的某个属性时,它将作为一个功能齐全的对象被故障化。
编辑:
来自评论:
不,你不是。您只需请求
Items
实体本身,然后记录它们。正如预期的那样,他们正在为自己的关系归还错误。只有当你向关系的另一方询问实际对象时,你才能保证看到对象而不是错误。这就是您需要强制关系中的对象出现错误:
您的另一个问题是您正在比较两个单独提取的结果。这:
... 记录 在获取发生之前的
mutableItemsFetchResults
。下一个 NSLog(大概)记录提取后的结果。这意味着您可能正在查看处于两种不同故障状态的两组不同对象。您可能还会遇到问题,因为
mutableItemsFetchResults
显然是一个属性,但您没有使用self.mutableItemsFetchResults
表示法来确保它被正确保留。另外,我认为您不需要mutableCopy
。A "fault" doesn't mean an error, it just means that the object returned is a "ghost" without its attributes read in. It's normal to get faults for the other side of relationship because you don't what a fetch to set off an uncontrolled cascade of object creation via its relationships.
When you access an attribute of the fault, it will be faulted in as a fully functional object.
Edit:
From comment:
No you're not. Your just requesting the
Items
entities themselves and then logging them. They are returning faults for their relationships as expected. Only if you ask each for the actual object on the other side of the relationship are you guaranteed to see an object instead of a fault.This is what you need to force the faulting-in of the objects in the relationship:
You're other problem is that you are comparing the results of two seperate fetches. This:
... logs the
mutableItemsFetchResults
before the fetch occurs. The next NSLog (presumably) logs the results after the fetch. This means you're looking at possibly two different sets of objects in two different fault states.You may also have a problem because
mutableItemsFetchResults
is apparently a property but you're not using theself.mutableItemsFetchResults
notation to make sure it is properly retained. Also, I don't think you need themutableCopy
.