难以调试iPhone Core Data错误

时间:2010-02-20 23:11:32

标签: iphone objective-c cocoa-touch core-data

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

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

这对于演讲者的关系来说很好,但是对于SECOND游戏来说,它一直都很糟糕。我以不同的方式重写了几次代码,我总是遇到同样的问题。并且问题存在,无论什么标题第二。所以我必须做一些根本上错误的事情,但是跟随更多iPhone 3开发中的核心数据章节没有任何事情发生在我身上。我希望有人可能会看到我所缺少的东西(已经过了好几天)。 (最后一点注意:无论是在for循环中还是在外部保存managedObjectContext,都会发生崩溃。总是在第二个会话中)。我无尽的感谢和第一个出生的孩子,无论谁能帮助我。

以下是保存会话实体的相关代码:

    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: (

2 个答案:

答案 0 :(得分:1)

听起来您的数据模型(应该)如下所示:

演讲者&lt; - &gt;&gt;会议
标题&lt; - &gt;&gt;会话

扬声器和标题各自与会话有多个关系

基于此:

  

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

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

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

答案 1 :(得分:0)

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

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

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