2010-02-20 27 views
0

我希望有人可以帮助我调试令人难以置信的Core Data崩溃。我最初将数据加载到两个实体(代表“发言人”和“标题”),然后为“会话”加载第三个实体,并尝试将关系设置为“发言人”和“标题”。 (从会话到演讲者和标题是一对一的,从演讲者/标题到会话是一对多的)。我使用整数键来设置每个关系。难以调试iPhone核心数据错误

由于给定的发言人和标题可以指向多个会话,因此我编写了一个搜索适当的托管对象并返回该对象的函数。然后我为这种关系做了设定。

这对于演讲者关系很好,但对于第二个标题一致而且可怕地崩溃。我用不同的方式重写了这些代码几次,我总是会遇到同样的问题。无论第二个标题是什么,问题都存在。所以我必须做一些根本性错误的事情,但继续阅读更多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: (
+0

如果你可以设置调试器并找出它到底崩溃的线路,它将会有很大的帮助。如果您发布数据模型的图表,这样也可以帮助我们清楚地看到这些关系。 – TechZen 2010-02-21 01:45:10

回答

1

这听起来像你的数据模型(应该)是这样的:

音箱< - >>会议
标题< - >>会议

凡扬声器和标题各有一个将关系分配给会话。

在此基础上:

我使用一个整数键设置每个 关系。

和你的代码,它看起来像你手动管理关系。你为什么做这个?!这是复杂和不必要的。在Core Data数据模型中设置并使用真实关系。

此外,不要使用“id”作为属性名称,因为它是Objective-C中的关键字。

0

谢谢,下面是数据模型的副本。你对基本的布局是正确的。

http://www.freeimagehosting.net/image.php?debf5866c1.jpg

原因我手动设定的关系是,因为这是第一次通过该程序,所以我从三个独立的Plist(一个用于扬声器,一个用于标题做数据的初始负荷,一个会议)。有一个更好的方法吗?我可能从根本上不理解核心数据,但似乎如果我每次创建会话实体时都创建了一个新的标题实体,我将拥有从标题到会话的一对一关系,而不是一对一的关系,我想要的很多关系。因此,我将id变量(现在我已经重命名,没有更改错误)作为第一次加载到核心数据中的关键字。之后,我当然会使用核心数据来管理所有这些。有一个更好的方法吗?

+0

首先,你有两个SO用户吗?为什么?接下来,您不应该为问题发布其他内容作为答案。您可以编辑原始问题或在适当的情况下创建新问题。 – gerry3 2010-02-23 18:32:32

+0

您可以从plists进行初始加载,也可以在开发过程中执行初始加载,然后保存该数据库文件并将其添加到项目中。然后,在您发布的应用程序中,您将将数据库文件从您的只读应用程序包复制到Documents目录中。请参阅http://stackoverflow.com/questions/2265333/how-to-populate-core-data-with-initial-data/2267000#2267000 – gerry3 2010-02-23 18:41:27

+0

您不了解核心数据关系。你应该做的第一件事是为你的实体创建子类。然后,您可以通过名称作为对象的属性访问属性和关系。多对多关系实际上是集合,因此您可以添加单个对象或一组对象,同时在Xcode中创建子类时为您提供方法。 – gerry3 2010-02-23 18:42:48