应用程序在其主键字段的对象 ID 的核心数据中崩溃

Posted

技术标签:

【中文标题】应用程序在其主键字段的对象 ID 的核心数据中崩溃【英文标题】:Application getting crashed in coredata for object ID for it's primary key field 【发布时间】:2013-05-27 12:41:58 【问题描述】:

我第一次使用Coredata,我正在为userinfo 实体设置一些值,从usergroups 实体中获取一些值。

在执行此过程时,我的应用程序崩溃说:

'项目之前没有为其主键分配对象 ID 字段,用于获取 Core Data 的永久 ID 目的。在调用保存 managedObjectContext 之前,请务必 分配对象 ID。

这看起来像

[newManagedObject setValue:[newManagedObject assignObjectId] forKey:[newManagedObject
 primaryKeyField]]

。有问题的项目是:

 <Userinfo: 0x10695b30>  (entity: Userinfo; id: 0x10695b70  <x-coredata://18875EDC-D300-4D63-90FC-181B2487599D-3229-000024DF842CC304/Userinfo/tA6216695-816F-4379-B24C-984AAFD1A8342>; data:

// 用于读取值和修改

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Userinfo" inManagedObjectContext:context];
    [fetchRequest setEntity:entity];
    NSPredicate *datapredicate = [NSPredicate predicateWithFormat:@"username == %@",usermobileNumber];
    [fetchRequest setPredicate:datapredicate];

    [context executeFetchRequest:fetchRequest onSuccess:^(NSArray *results)
        NSLog(@"results %@",[results valueForKey:@"firstname"]);
        userinfoObject = [results objectAtIndex:0];
        NSLog(@"userinfo %@",userinfoObject);
//        userinfoObject = [[Userinfo alloc]initWithEntity:[NSEntityDescription entityForName:@"Userinfo" inManagedObjectContext:context] insertIntoManagedObjectContext:context];

        [userinfoObject setValue:[userinfoObject valueForKey:@"firstname"] forKey:@"firstname"];
        [userinfoObject setValue:[userinfoObject valueForKey:@"lastname"] forKey:@"lastname"];
        [userinfoObject setValue:[userinfoObject valueForKey:@"email"] forKey:@"email"];
        [userinfoObject setValue:[userinfoObject valueForKey:@"zipcode"] forKey:@"zipcode"];
        [userinfoObject setValue:[userinfoObject valueForKey:@"password"] forKey:@"password"];
        [userinfoObject setValue:[userinfoObject valueForKey:@"dateofbirth"] forKey:@"dateofbirth"];
        [userinfoObject setValue:[userinfoObject valueForKey:@"username"] forKey:@"username"];
        [userinfoObject setValue:[userinfoObject valueForKey:@"salutation"] forKey:@"salutation"];
//        [userinfoObject setValue:[userinfoObject assignObjectId] forKey:[userinfoObject primaryKeyField]];

// 加值

Usergroups *userGroupsObject = [NSEntityDescription insertNewObjectForEntityForName:@"Usergroups" inManagedObjectContext:context];
            [userGroupsObject setValue:contactObject.strGroupName forKey:@"groupname"];
            [userGroupsObject setValue:[contactsStack objectAtIndex:i] forKey:@"mobile_contacts"];
            [userGroupsObject setValue:usermobileNumber forKey:@"mobile_number"];
            [userGroupsObject setValue:[userGroupsObject assignObjectId] forKey:[userGroupsObject primaryKeyField]];
            NSError *error = nil;
            if (![context saveAndWait:&error]) 
                NSLog(@"There was an error! %@", error);
            
            else 
                NSLog(@"You created Usergroup object!");
            
            [userinfoObject addUsergroupsObject:userGroupsObject];

【问题讨论】:

primaryKeyField 方法有什么作用?这不是标准的核心数据方法,它似乎是你麻烦的原因。这是哪里来的? @TomHarrington :这与我正在使用的数据库以及特定的 Nsmanaged 对象上下文有关,即我将 objectId 分配给数据库创建的默认主键的用户组对象。 好吧,我真的不明白你在说什么,但如果要乱搞 NSManagedObject 的 objectID,你肯定会崩溃和/或数据损坏。 【参考方案1】:

你应该提供更多的代码............

通常添加新条目将如下所示

FormField *info = [NSEntityDescription
                    insertNewObjectForEntityForName:@"FormField"
                    inManagedObjectContext:managedObjectContext];


[info setValue: @"string data to insert" forKey:@"fieldValue"];
NSError *error;
[managedObjectContext save:&error]

检索条目将如下所示

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:@"entityName"
                                    inManagedObjectContext:managedObjectContext]];

NSError *error;
NSArray* data_ = [managedObjectContext executeFetchRequest:fetchRequest error:&error];

【讨论】:

原因是您正在尝试使用刚刚创建但尚未保存的核心数据对象的对象ID...只要您在托管对象上下文上调用保存,该对象就会获取其ID。 要么在该行之前调用管理对象上下文的保存或更改逻辑............【参考方案2】:

assignObjectID 和 primaryKeyField 方法让那些试图回答这个问题的人望而却步,因为它们是 StackMob 特定的方法。它们根本不直接与 Core Data ID 交互,它们只是将随机生成的 UUID 分配给映射到数据库(StackMob 服务器)中的主键字段的属性。实际上,在调用 save 之前必须执行此操作,因为增量存储实现然后使用该字符串 ID 在覆盖的 gainPermanentIDsForObjects: 方法中创建永久核心数据 ID。

我在这里的猜测是,您有一个托管对象,在它保存之前,它永远不会为映射到数据库主键字段的属性分配一个值。在导致崩溃的保存之前,设置断点并打印出托管对象上下文的插入对象(即 [self.managedObjectContext insertedObjects])。这应该让您了解导致崩溃的对象,并且您可以相应地调整您的代码。

【讨论】:

是的,用户对象有空值,msv 你对stackmob有什么想法吗?? 我需要发送一个用户组对象到一个特定的用户对象,用户名是主键,我怎样才能做到这一点..

以上是关于应用程序在其主键字段的对象 ID 的核心数据中崩溃的主要内容,如果未能解决你的问题,请参考以下文章

即使其主键ID号小于输入的较早行,如何使行保持其条目位置

jdbc-mysql基础 ResultSet getGeneratedKeys 插入一条字段并返回其主键

keyProperty="id" 和useGeneratedKeys="true"作用

Choreographer: Skipped frames : 应用程序可能在其主线程上做太多工作

如何使用 Hibernate 插入记录正确自动生成主键 ID

向Mysql主键自增长表中添加数据并返回主键