难以调试 iPhone Core Data 错误
Posted
技术标签:
【中文标题】难以调试 iPhone Core Data 错误【英文标题】:Having difficulty debugging a iPhone Core Data bug 【发布时间】:2010-02-20 23:11:32 【问题描述】:我希望有人可以帮助我调试一个令人难以置信的令人沮丧的 Core Data 崩溃。我最初将数据加载到两个实体(代表“演讲者”和“标题”)中,然后为“会话”加载第三个实体,并尝试将关系设置为“演讲者”和“标题”。 (从会话到演讲者和标题是一对一的。从演讲者/标题回到会话是一对多的)。我使用整数键来设置每个关系。
由于给定的演讲者和标题可以指向多个会话,我编写了一个函数来搜索适当的托管对象并返回该对象。然后我为关系设置它。
这对于说话者关系来说效果很好,但对于 SECOND 标题来说却始终如一且可怕地崩溃。我已经以不同的方式重写了几次代码,但我总是遇到同样的问题。无论什么标题排在第二位,问题都存在。所以我必须做一些根本上错误的事情,但是按照更多 iPhone 3 开发中的核心数据章节,我没有任何反应。我希望有人可能会看到我缺少的东西(并且已经好几天了)。 (最后一点:无论我将 managedObjectContext 保存在 for 循环内还是外部都会发生崩溃。总是在第二个会话中)。我对任何可以帮助我的人表示无尽的感谢和第一个出生的孩子。
以下是保存会话实体的相关代码:
for (NSDictionary *session in self.sessions)
NSManagedObject *newSession = [NSEntityDescription insertNewObjectForEntityForName:[sessionEntity name] inManagedObjectContext:self.managedObjectContext];
[newSession setValue:[session valueForKey:@"ID"] forKey:@"id"];
[newSession setValue:[session valueForKey:@"notes"] forKey:@"notes"];
[newSession setValue:[session valueForKey:@"length"] forKey:@"length"];
//get the speaker value;
[newSession setValue:[self setupSpeaker:[session valueForKey:@"speaker"]] forKey:@"speaker"];
NSLog(@"now doing title");
//now get the title value;
[newSession setValue:[self setupTitle:[session valueForKey:@"title"]] forKey:@"title"];
NSLog(@"I got back this title:%@", [newSession valueForKey:@"title"]);
if (![self.managedObjectContext save:&error])
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
这是为关系找到合适的说话者和标题实体的代码(我意识到这很多余)
-(NSManagedObject *) setupSpeaker:(NSNumber *)id
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Speaker" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"id==%@",id];
[fetchRequest setPredicate:predicate];
NSError *error;
NSArray *items=[self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
[fetchRequest release];
if ([items count]>=1)
return [items objectAtIndex:0];
else
return 0;
-(NSManagedObject *) setupTitle:(NSNumber *)id
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Title" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSLog(@"now looking for: %@", id);
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"id==%@",id];
[fetchRequest setPredicate:predicate];
NSError *error;
NSArray *items=[self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
[fetchRequest release];
if ([items count]>=1)
NSLog(@"found %@", id);
return [items objectAtIndex:0];
else
return 0;
最后是崩溃时的日志:
2010-02-20 16:48:17.134 iconf[1438:207] now looking for: 1
2010-02-20 16:48:17.136 iconf[1438:207] found 1
2010-02-20 16:48:17.156 iconf[1438:207] I got back this title:<NSManagedObject: 0x3b11a10> (entity: Title; id: 0x3d4a3c0 <x-coredata://B76F62BD-AC82-4335-9013-7529C2471F9C/Title/p6> ; data:
id = 1;
session = (
0x3d51640 <x-coredata:///Session/t2765697F-14C9-4282-A067-10A2413732B834>
);
title = "Bill Gates Speaks";
)
2010-02-20 16:48:17.158 iconf[1438:207] now doing title
2010-02-20 16:48:17.158 iconf[1438:207] now looking for: 2
2010-02-20 16:48:17.159 iconf[1438:207] found 2
2010-02-20 16:48:17.161 iconf[1438:207] I got back this title:<NSManagedObject: 0x3b16fd0> (entity: Title; id: 0x3d4d7a0 <x-coredata://B76F62BD-AC82-4335-9013-7529C2471F9C/Title/p12> ; data:
id = 2;
session = (
0x3b1b320 <x-coredata:///Session/t2765697F-14C9-4282-A067-10A2413732B835>
);
title = "Lecture on Frogs";
)
2010-02-20 16:48:17.161 iconf[1438:207] *** -[NSManagedObject compare:]: unrecognized selector sent to instance 0x3b11a10
2010-02-20 16:48:17.162 iconf[1438:207] Serious application error. Exception was caught during Core Data change processing: *** -[NSManagedObject compare:]: unrecognized selector sent to instance 0x3b11a10 with userInfo (null)
2010-02-20 16:48:17.163 iconf[1438:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSManagedObject compare:]: unrecognized selector sent to instance 0x3b11a10'
2010-02-20 16:48:17.163 iconf[1438:207] Stack: (
【问题讨论】:
如果您可以设置调试器并准确找出它在哪一行崩溃,这将有很大帮助。如果您发布数据模型的图片也会有所帮助,以便我们清楚地看到关系。 【参考方案1】:听起来您的数据模型(应该)如下所示:
演讲者 > 会议 标题 > 会议
Speaker 和 Title 都与 Session 有一对多关系。
基于此:
我使用一个整数键来设置每个 关系。
和您的代码,看起来您正在手动管理关系。你为什么做这个?!这是复杂且不必要的。在您的 Core Data 数据模型中设置和使用真实关系。
此外,不要使用“id”作为属性名称,因为它是 Objective-C 中的关键字。
【讨论】:
【参考方案2】:谢谢,下面是数据模型的副本。您对基本布局的看法是正确的。
http://www.freeimagehosting.net/image.php?debf5866c1.jpg
我手动设置关系的原因是因为这是第一次通过程序,所以我从三个单独的 plist(一个用于演讲者,一个用于标题,一个用于会话)进行数据的初始加载。有一个更好的方法吗?我可能根本不了解核心数据,但似乎每次创建会话实体时我只是创建了一个新的标题实体,我将在标题与会话之间建立一对一的关系,而不是一对一的关系我想要的很多关系。因此,我放入了 id 变量(我现在已将其重命名,错误没有改变)作为第一次加载到核心数据的键。在那之后,我当然会使用核心数据来管理所有这些。有没有更好的方法来做到这一点?
【讨论】:
首先,您有两个 SO 用户吗?为什么?接下来,您永远不应该发布问题的其他内容作为答案。如果合适,您可以编辑原始问题或创建新问题。 您可以从 plist 进行初始加载,或者您可以在开发期间进行初始加载,然后保存该数据库文件并将其添加到您的项目中。然后,在您发布的应用程序中,您可以将只读应用程序包中的数据库文件复制到 Documents 目录中。见***.com/questions/2265333/… 您不了解 Core Data 关系。您应该做的第一件事是为您的实体创建子类。然后,您可以通过它们的名称访问属性和关系作为对象的属性。对多关系实际上是集合,因此您可以使用在 Xcode 中创建子类时为您提供的方法添加单个对象或一组对象。 是的,我对我滥用堆栈溢出表示诚挚的歉意。我不小心匿名发布了我的第一个帖子,因此当我发布带有附加详细信息的评论时,由于评分低,我无法以自己的身份发表评论。不管怎样,我以后会做得更好。我只是找出错误。在上面我发布的代码中,我在“标题”上使用了 fetchedResultsController 来检查是否有任何结果。我摆脱了它,我很高兴去。再次感谢您对菜鸟的耐心。以上是关于难以调试 iPhone Core Data 错误的主要内容,如果未能解决你的问题,请参考以下文章
是否可以在开发 iphone 上查看存储在 Core Data 中的数据?
在 iPhone 应用程序关闭并重新打开之前,Core Data 信息不显示的问题