iOS核心数据瞬态是如何工作的?

iOS核心数据瞬态是如何工作的?,ios,core-data,nsmanagedobject,nsmanagedobjectcontext,Ios,Core Data,Nsmanagedobject,Nsmanagedobjectcontext,我试图理解iOS核心数据的瞬态属性,但在理解某些行为时遇到困难 设置 我有两个上下文:主上下文和私有上下文。我称之为mainContext和threadedContext 线程上下文是父上下文,主上下文是子上下文。(我这样做是因为我的线程上下文改变模型的频率远远高于我的主线程和UI 我有暂时的属性,我需要通过上下文传递它们的值 我发现有时我失去了价值,有时我不依赖于我如何运作 样本 这段代码已经被简化以显示问题。我有一个Person对象。Person对象有一个名为“other”的临时实体,您将看

我试图理解iOS核心数据的瞬态属性,但在理解某些行为时遇到困难

设置

我有两个上下文:主上下文和私有上下文。我称之为mainContext和threadedContext

线程上下文是父上下文,主上下文是子上下文。(我这样做是因为我的线程上下文改变模型的频率远远高于我的主线程和UI

我有暂时的属性,我需要通过上下文传递它们的值

我发现有时我失去了价值,有时我不依赖于我如何运作

样本

这段代码已经被简化以显示问题。我有一个Person对象。Person对象有一个名为“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不再设置(请注意,在检索对象之前我正在保存)

我尝试了不同的方法,包括refreshObject:mergChanges: 我试着观察物体何时出故障,但这似乎没有什么帮助。 即使当前没有实例化任何模型对象,瞬态值是否存储在给定的上下文中(假设我已保存,或者可能没有给出我看到的问题)

对于那些觉得需要更多的人。。。 getPersonOnContext:WithID方法如下所示:

- (Person *)getPersonOnContext:(NSManagedObjectContext *)context withID:(NSManagedObjectID *)ID
{
    __block Person *person = nil;
    [context performBlockAndWait:^{
        person = (Person *)[context objectWithID:ID];
    }];
    return person;
} 
- (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;
}
createAPersonOnContext:如下所示:

- (Person *)getPersonOnContext:(NSManagedObjectContext *)context withID:(NSManagedObjectID *)ID
{
    __block Person *person = nil;
    [context performBlockAndWait:^{
        person = (Person *)[context objectWithID:ID];
    }];
    return person;
} 
- (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上有:

更新:

在使用ID检索线程上下文中的对象之前进行保存时,它似乎是在破坏临时值的Person对象上出错。如果在保存之前在线程上下文中检索对象,则临时值将被保留,因为对象没有出现故障。

maxpower

瞬变是非常简单的。它们是后备存储器中始终不存在的属性。因此,你看到它们的事实是因为你正在使用一个子MOC,并且外部指定了这些值。为了确保瞬变总是有效的,你需要考虑实现<代码> -AWEKORFRONMYSTRT ,<代码> -AUKEFFR。omFetch,

-preparefordelection
-didTurnIntoFault
-willturintofault
方法


Andrew

为了理解核心数据,你可以阅读raywenderlich的教程。就我所见,该教程没有讨论瞬变。你定义“其他”有什么特别的原因吗属性为瞬态?Scott,是的,但这不是问题的所在…我的内存中有不需要存储在磁盘上的信息。如果对象成为故障,则在该故障发生时,它将失去其瞬态属性。保存的对象可能会成为故障,但会破坏上下文,这取决于核心数据的管理方式e内存。保存子上下文将把更改推送到其父内容中,而不是保存到存储中。您可以监视是否在保存子上下文时发生此情况,并将其转化为故障。对,我理解这一点。但如果我在contextA中设置了瞬态,我就不必在contextB中重新设置瞬态属性的值。对吗?这就是瞬变的全部意义,即在你的模式中保持非持久性的能力,作为奖励,你可以跨上下文保持信息。maxpower,我相信你错了。根据我的经验,瞬变从来没有离开过他们的MOC。这在父母/孩子MOC关系中可能不是严格正确的。根据你的经验判断,孩子MOC有时可以在父母MOC中看到瞬态的值。由于瞬态没有保存,父母永远不应该看到孩子的瞬态ivar的值。证据在代码中。这在一个比你展示的简单的示例项目中相对容易测试。Andrewadonoho,进一步的研究表明你是正确的。瞬态瞬态不会可靠地跨上下文,如果您在非父/子设置中有多个上下文,则瞬态永远不会跨上下文。这应该在苹果的文档中明确说明。maxpower,如果您同意我已回答了您的问题,请检查检查。安德烈维认为答案本身离问题太远。此外,Scotts answer/评论我提出的问题回答了与问题结构相关的更多核心问题。编辑你的答案,我可能会检查它:)