我正在尝试了解iOS核心数据瞬态属性,并且无法理解某些行为。
设置
我有两个上下文主要和私有上下文。我称之为mainContext和threadedContext。
线程上下文是父上下文,主上下文是子上下文。 (我这样做是因为我的线程上下文比我的主线程和UI更频繁地改变模型。
我有瞬态属性,我需要通过上下文传递它。
我发现有时候我放松了价值,有时我并不依赖于我的运作方式。
示例
此代码已经过简化以显示问题。我有一个Person对象。 Person对象有一个名为“other”的瞬态实体,你会看到我为它指定了一个具有几个简单属性的Other对象,仅此而已。
- (void)case1
{
NSManagedObjectContext *mainThreadContext = [AppDelegate appDelegate].mainThreadContext;
NSManagedObjectContext *threadedContext = [AppDelegate appDelegate].threadedContext;
__block NSManagedObjectID *objectID = nil;
[mainThreadContext performBlockAndWait:^{
//create
Person *aPerson = [self createAPersonOnContext:mainThreadContext];
//setup
Other *other = [[Other alloc] init];
aPerson.other = other;
aPerson.other.favoriteColor = @"Blue";
aPerson.other.city = @"Provo";
//save
NSError *error = nil;
[mainThreadContext save:&error];
objectID = aPerson.objectID;
NSLog(@"%@",aPerson);
}];
}
当我像这样检索对象时,仍然设置了person.other属性(注意我在检索对象后保存:
[threadedContext performBlockAndWait:^{
Person *aPerson = [self getPersonOnContext:threadedContext withID:objectID];
NSError *threadedError = nil;
[threadedContext save:&threadedError];
NSLog(@"threaded %@", aPerson);
}];
当我像这样检索对象时,不再设置person.other(请注意我在检索对象之前保存)
[threadedContext performBlockAndWait:^{
NSError *threadedError = nil;
[threadedContext save:&threadedError];
Person *aPerson = [self getPersonOnContext:threadedContext withID:objectID];
NSLog(@"threaded %@", aPerson);
}];
我尝试了不同的东西,包括refreshObject:mergChanges: 我试图观察物体何时出现故障,但似乎没有帮助。 瞬态值是否存储在给定的上下文中(假设我已经保存,或者可能没有给出我看到的问题),即使当前没有实例化模型对象?
对于那些觉得自己需要更多的人...... 方法getPersonOnContext:WithID如下所示:
- (Person *)getPersonOnContext:(NSManagedObjectContext *)context withID:(NSManagedObjectID *)ID
{
__block Person *person = nil;
[context performBlockAndWait:^{
person = (Person *)[context objectWithID:ID];
}];
return person;
}
createAPersonOnContext:如下所示:
- (Person *)createAPersonOnContext:(NSManagedObjectContext *)context
{
__block Person *person = nil;
[context performBlockAndWait:^{
person = (Person *)[NSEntityDescription insertNewObjectForEntityForName:@"Person"
inManagedObjectContext:context];
person.firstName = @"matt";
person.lastName = @"ZZZ";
}];
return person;
}
我只是想隐藏这段代码,以帮助引起对自身问题的关注。
如果你想试验一下,我可以在github上找到它:https://github.com/mcmurrym/CoreDataBehaviors
更新
看来,当我在使用ID之前保存,在线程上下文中检索对象时,会破坏Person对象,从而破坏瞬态值。如果我在保存之前在线程上下文中检索对象,则会保留瞬态值,因为该对象不会出现故障。
答案 0 :(得分:4)
牛魔王,
瞬态非常简单。它们是后备存储中始终不存在的属性。因此,您看到它们的事实是因为您正在使用子MOC并从外部分配这些值。为确保瞬态始终有效,您需要考虑实施-awakeFromInsert
,-awakeFromFetch
,-prepareForDeletion
,-didTurnIntoFault
和-willTurnIntoFault
方法。
安德鲁