假设我有一个类(NSManagedObject的子类)。每次用户单击按钮时,都会创建一个新的Person实例并将其添加到全局NSMutableArray中。另外,新创建的Person实例将被添加到子上下文中,如下所示:
NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType: NSPrivateConcurrencyType];
[childContext setParentContext: _mainContext];另外,当单击按钮时,我保存上下文:(它有点复杂,但遵循以下结构)
[childContext performBlock:^{
[childContext save:nil];
[_mainContext save:nil];
}];在单击两次或更多次(不确定是否取决于单击总数)之后,我的数组中的按钮对象将变成fault。
根据docs:访问错误对象的属性应该加载持久对象。
即使在访问NSManagedObject的属性时,对象仍然是错误的,属性是nil。
为什么对象在我的数组中是错误的,我如何访问一个错误对象的属性?
编辑
在加载UIViewController时,我从数据存储中获取所有现有对象:
-(NSArray*)fetchPersons {
NSManagedObjectContext *context = [self managedObjectContext]; //this is _mainContext, it is created with initWithConcurrencyType:NSMainQueueConcurrencyType
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *description = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:context];
[fetchRequest setEntity:description];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"key = %i", aCondition];
[fetchRequest setPredicate:predicate];
return [context executeFetchRequest:fetchRequest error:nil];
}我正在使用来自fetchPersons的这个fetchPersons来填充NSMutableArray。
创建一个新的Person对象:
-(Person*)createPerson {
NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType: NSPrivateQueueConcurrencyType];
[childContext setParentContext:[self managedObjectContext]];
Person *person = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:childContext];
return person;
} 我不知道如何用“bjectID`”来处理对象。我使用childContext作为临时上下文。有时我需要一个Person实例,但我不想将它保存到持久存储中(或者在开始时将它插入主上下文)。
经过所有这些步骤之后,我的NSMutableArray中有了所有的对象。在创建一些对象之后,我获得了零属性(故障对象),并尝试记录它们的属性(person.name或其他什么)。
发布于 2013-02-07 20:19:45
NSManagedObject与创建它们的NSManagedObjectContext保持着紧密的关系。造成这种情况的具体原因是托管对象总是可变的,因此可能需要写回存储,而且未来可能会出现故障-- Core数据可能显式地选择不将整个持久存储加载到内存中,但可能必须处理对象图的未来任意遍历或内存警告低的问题。
(旁白:这也是核心数据对象除了在线程/队列上创建之外不能使用的最接近的原因;上下文和对象之间的隐式通信是不安全的。)
实际上,这意味着您不应该允许托管对象超过其存储空间。
为了允许您在具有不同上下文的不同代理之间来回发送对象,Apple实现了NSManagedObjectID,它是任何托管对象的唯一标识符。它是一个完全不透明的类,但是作为信息,如果您有一个SQLite存储,那么它就是对相关表和行的引用;如果您有其他存储类型之一,那么它类似地是指向存储中某个位置的指针。它本身不携带任何对象数据。
因此,您通常要做的是在对象创建的上下文仍然存在的情况下,调用对象的objectID。然后你可以把它传递给其他人。然后,他们将使用[myManagedObjectContext -existingObjectWithID:error:]获得一个新的托管对象副本,可以安全地使用。新的副本将绑定到该上下文,而不是原件,因此无论何时和多久,该上下文都是安全的,而不是原件。
唯一可能的惊喜是,当您第一次插入一个对象时,它只获得一个临时的对象ID。这是因为Core数据喜欢对需要插入到存储中的东西进行分批处理,然后只在请求保存时立即将它们全部插入。
出于您的目的,您不希望将ID传递到保存之后,因为对象将不存在于父存储中。因此,这一点在一定程度上是学术性的,但如果您出于其他原因想要查询ID,您还可以考虑使用上下文的-obtainPermanentIDsForObjects:error:,它可以比实际的保存速度快得多,这取决于您的存储类型,而且绝对不会慢。
https://stackoverflow.com/questions/14738726
复制相似问题