【问题标题】:Issue With NSManagedObjectID when using as property用作属性时 NSManagedObjectID 出现问题
【发布时间】:2012-12-13 10:17:08
【问题描述】:

我正在尝试通过其唯一对象来获取对象,为此我正在保存插入对象的 ID,我将使用它来获取它,这是我的代码。

@implementation UserInfoDOA
@synthesize firstName,lastName,userName,bDate,department,searchByDept,searchByName,moid,uriData,uri;

- (NSString *)insertUser
{    
    UserInfoAppDelegate *delegate = (UserInfoAppDelegate *)[[UIApplication sharedApplication] delegate];
    UserInfo *newUser = [NSEntityDescription insertNewObjectForEntityForName:@"UserInfo"
                                  inManagedObjectContext:delegate.managedObjectContext];


    Department *dept = [NSEntityDescription insertNewObjectForEntityForName:@"Department"
                                                   inManagedObjectContext:delegate.managedObjectContext];

    moid = [newUser objectID];
    NSLog(@"IN INSERTUSER %@", moid);  // moid displays its value

    if(dept!=nil) {
        dept.id=@"1001";
        dept.name=department;
        dept.location=@"ahmedabad";
        dept.post=@"developer";        
    }

    if (newUser != nil) {
        newUser.firstName =firstName;
        newUser.lastName =lastName;
        newUser.userName=userName;
        newUser.bDate = bDate ;
        newUser.dept=dept;

        NSError *savingError = nil;

        if ([delegate.managedObjectContext save:&savingError]) {
            NSLog(@"Successfully saved the context.");
        }
        else {       
            NSLog(@"Failed to save the context. Error = %@", savingError);
        }
    }
    else {        
        NSLog(@"Failed to create the new person.");
    }

    NSLog(@"IN INSERTUSER after %@",moid);

    return @"true";
}

- (NSArray *) getUser
{
    NSLog(@"IN GETUSER %@", moid); //NOT WORKING, moid is NULL here

    UserInfoAppDelegate *delegate = (UserInfoAppDelegate *)[[UIApplication sharedApplication] delegate];


    NSEntityDescription *entity = [NSEntityDescription entityForName:@"UserInfo"
                                              inManagedObjectContext:delegate.managedObjectContext];

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setEntity:entity];


    NSPredicate *predicate=[NSPredicate predicateWithFormat:@"(objecId = %@)",moid];


    [fetchRequest setPredicate:predicate];

    NSError *requestError = nil;
    NSArray *users = [delegate.managedObjectContext executeFetchRequest:fetchRequest                     
                                                                  error:&requestError];

    return users;    
}

那么这里有什么问题呢?尽管我已存储为属性,但我无法在第二个函数中访问 moid

【问题讨论】:

    标签: iphone core-data nsmanagedobject


    【解决方案1】:

    首先,您是否使用 ARC?

    那么,为什么会这样呢?

    - (NSString *)insertUser
    {
        // other code here
    
        return @"true"
    }
    

    改用这个

    - (BOOL)insertUser
    {
        // other code here
    
        return YES // or NO based on the insertion result
    }
    

    那么,就用这个方法

    - (NSArray *)getUser
    

    - (UserInfo *)getUser
    {
        // other code here
    
        // maybe you should add some code for error handling...you haven't set up any code there...
        return [users objectAtIndex:0];
    }
    

    关于你的问题,你不应该依赖NSManagedObjectID

    正如@MarcusS.Zarra 建议的那样

    不保证 NSManagedObjectID 是一致的。它可以 根据包括数据迁移和其他因素在内的许多因素进行更改 因素。如果您使用它作为您的唯一标识符 对象,停止。

    因此,在您的模型中为UserInfo 实体添加一个属性(NSString 可以),并在您创建新用户和检索用户时设置它。

    // insert
    user.userIdentifier = // your identifier
    
    // retrieve
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(userIdentifier == %@)", self.moid];
    

    现在在哪里moid will be

    @property (nonatomic, copy) NSString* moid; // also synthesize it (optional)
    

    将被设置为

    self.moid = [newUser userIdentifier];
    

    要创建新标识符,您可以查看 CORE DATA objectId changes constantly 或创建自己的算法来生成它。

    附:我认为您没有使用 ARC,因为编译器会抱怨 newUser

    【讨论】:

    • 是的,我正在使用启用 ARC 的环境,我试图保存唯一的 ID,然后在获取具有该 ID 的对象以进行更新。
    【解决方案2】:

    对象 ID 有两种形式。首次创建托管对象时,Core Data 为其分配一个临时 ID;只有当它被保存到持久存储时,Core Data 才会为托管对象分配一个永久 ID。您可以很容易地发现一个 ID 是否是临时的:

    BOOL isTemporary = [[managedObject objectID] isTemporaryID];
    

    保存上下文后,您的对象 ID 可能会发生变化。

    【讨论】:

    • 我在保存 newUser 后检查了这个,它给出了 NULL! BOOL isTemporary = [[newUser objectID] isTemporaryID]; NSLog(@"IS TEMP: %@",isTemporary);
    • 实际上 %@ 用于在引用处打印对象。所以 NSLog(@"IS TEMP: %@",isTemporary);是错的。因为 No 返回 0 并且它在 ) 地址找到 Null。
    • 这意味着您的 isTemprory 正在返回 NO
    猜你喜欢
    • 1970-01-01
    • 2011-06-08
    • 2022-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-04
    相关资源
    最近更新 更多