初始化托管对象时,核心数据对象属性为nil,无需插入托管对象上下文

时间:2016-05-18 19:09:17

标签: ios objective-c core-data nsmanagedobject nsmanagedobjectcontext

在我的Core Data应用程序中,我正在使用带有initWithEntity:insertIntoManagedObjectContext:上下文的nil初始化托管对象。我正在使用[managedObjectContext insertObject:object]将对象插入Context中,如果需要的话。

这似乎是insertObject: API存在的原因。插入在创建期间未插入的托管对象。

但是当使用上述逻辑时,对象(稍后从MOC获取)具有nil属性。对象上的字符串不会保留。

如果我改为使用{{1>} 非零 MOC,则属性 会保持不变,一切正常。在这种情况下,我不会致电initWithEntity:insertIntoManagedObjectContext:

代码的两个差异如下。只需切换insertObject:标志即可尝试各自。

useNilContext

稍后,当我从Core Data中获取对象并检查它时,我会得到不同的行为,具体取决于对象是否最初插入到MOC中。如果MOC为// ... BOOL useNilContext = YES; [[XYZBackend sharedBackend].managedObjectContextPrivateQueue performBlock:^{ XYZObject *object = [XYZObject objectFromJSON:json useNilContext:useNilContext]; if (useNilContext) { [[XYZBackend sharedBackend].managedObjectContextPrivateQueue insertObject:object]; } NSError *privateQueueError = nil; if (![[XYZBackend sharedBackend].managedObjectContextPrivateQueue save:&privateQueueError]) { NSLog(@"Error saving Core Data managed object context in private queue! %@", privateQueueError); } }]; // ... + (instancetype)managedObjectFromJSON:(NSDictionary *)json useNilContext:(BOOL)useNilContext { __block XYZManagedObject *object = nil; [[XYZBackend sharedBackend].managedObjectContextPrivateQueue performBlockAndWait:^{ NSEntityDescription *entity = [NSEntityDescription entityForName:NSStringFromClass([self class]) inManagedObjectContext:[XYZBackend sharedBackend].managedObjectContextPrivateQueue]; NSManagedObjectContext *context = [XYZBackend sharedBackend].managedObjectContextPrivateQueue; if (useNilContext) { context = nil; } object = [[XYZManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:context]; object.stringProperty = json[@"string"]; }]; return object; } ,则在获取后所有对象的属性都为nil

nilinitWithEntity:insertIntoManagedObjectContext: MOC一起使用:

nil

使用非零MOC初始化:

Printing description of object:
<XYZObject: 0x60b0000b80d0> (entity: XYZObject; id: 0xd000000000040000 <x-coredata://5F843602-C03B-4339-AC50-0F70FD1545C9/XYZObject/p1> ; data: {
    stringProperty = nil;
})

如您所见,当对象最初未插入MOC时,在获取后属性为Printing description of object: <XYZObject: 0x60b000054680> (entity: XYZObject; id: 0xd000000000040000 <x-coredata://72502855-7204-4485-828C-BC07C51F7FE2/XYZObject/p1> ; data: { stringProperty = "string"; }) 。当它最初插入MOC时,属性是非零并且持久存在。

为什么这些属性不会持久存在?我认为这两个代码策略应该是相同的。

是否还需要采取另一个步骤来持久保存最初具有nil托管对象上下文的托管对象的属性?

1 个答案:

答案 0 :(得分:1)

不,没有额外的步骤。至于为什么没有保存属性,你的代码中还会出现导致问题的其他因素。无论是提供上下文还是使用nil上下文,然后插入对象,分配新的托管对象都是一样的。

看起来你可能会混淆上下文,但很难确定。当您致电insert:时,请使用[TDBackend sharedBackend].managedObjectContextPrivateQueue。但是当您保存更改时,使用self.managedObjectContextPrivateQueue。同时,当useNilContextNO时,您可以使用[XYZBackend sharedBackend].managedObjectContextPrivateQueue创建托管对象。而且你正在使用[ZYZBackend sharedBackend].managedObjectContextPrivateQueue上的阻止调用来同步事物。这应该是一个相当简单的代码中的四种不同的上下文。这是不可能肯定的,但它给人的印象是你在某个时候使用了错误的语境