我的情况:假设我有一个类Person(NSManagedObject的子类).每次用户单击按钮时,都会创建一个新的Person实例并将其添加到全局NSMutableArray中.此外,新创建的Person实例将添加到子上下文中,如下所示:
NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType: NSPrivateConcurrencyType];
[childContext setParentContext: _mainContext];
Run Code Online (Sandbox Code Playgroud)
此外,当单击按钮时,我保存上下文:(它有点复杂,但遵循此结构)
[childContext performBlock:^{
[childContext save:nil];
[_mainContext save:nil];
}];
Run Code Online (Sandbox Code Playgroud)
单击两次或多次(不确定是否取决于总点击次数)后,我的数组中的按钮对象就变为了fault.
根据文档:访问故障对象的属性应该加载持久对象.
即使我访问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];
}
Run Code Online (Sandbox Code Playgroud)
我正在使用这个NSArray fetchPersons来填充NSMutableArray.
创建一个新的Person对象:
-(Person*)createPerson {
NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType: NSPrivateQueueConcurrencyType];
[childContext setParentContext:[self managedObjectContext]];
Person *person = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:childContext];
return person;
}
Run Code Online (Sandbox Code Playgroud)
我不确定如何使用òbjectID`处理对象.我正在使用childContext作为临时上下文.有时我需要一个Person实例,但我不想将它保存到持久性存储(或者在开头将其插入主上下文).
完成所有这些步骤后,我的NSMutableArray中包含了所有对象.在创建一些对象并尝试记录它们的属性(person.name或其他东西)后,我得到了nil属性(fault对象).
Tom*_*mmy 18
NSManagedObject与NSManagedObjectContext他们创建的关系保持紧密的关系.具体原因是托管对象总是可变的,因此可能需要回写到商店,并且期望未来的错误 - 核心数据显然可以选择不将整个持久性存储加载到内存中但可能必须处理您将来对对象图的任意遍历或低内存警告.
(除此之外:这也是为什么Core Data对象不能用于创建它们的线程/队列以外的任何东西的最接近的原因;它是上下文和上下文与对象之间的隐式通信的各个位.安全)
在实践中,这意味着您不应该允许托管对象超过其商店.
为了允许您在具有不同上下文的不同代理之间来回发送对象,Apple实现了NSManagedObjectID哪个是任何托管对象的唯一标识符.它是一个完全不透明的类,但是,作为信息,如果你有一个SQLite存储,那么它是对相关表和行的引用; 如果你有其他商店类型之一,那么它同样是指向商店中某个位置的指针.它不携带任何对象数据本身.
所以你通常做的是调用objectID一个对象,而它创建的上下文仍然存在.然后,您可以将其传递给其他人想要它.然后,他们将使用[myManagedObjectContext -existingObjectWithID:error:]获取可以安全使用的托管对象的新副本.新副本将绑定到该上下文而不是原始上下文,因此无论何时上下这个上下文是安全的,都是安全的,而不是原始的.
唯一可能的惊喜是,当您第一次插入对象时,它只获得一个临时对象ID.这是因为Core Data喜欢批量处理需要插入商店的内容,然后只在您请求保存时才将它们全部插入.
出于您的目的,您不希望在保存之后直到ID,因为该对象将不存在于父存储中.所以这一点部分是学术性的,但是假设你想出于其他原因想要去掉ID,你也可以考虑使用上下文-obtainPermanentIDsForObjects:error:,这可能比实际保存要快很多,具体取决于你的商店类型,绝对不会是慢点.
| 归档时间: |
|
| 查看次数: |
4216 次 |
| 最近记录: |