2

iOS Core データの一時的なプロパティを理解しようとしていますが、いくつかの動作を理解するのに問題があります。

設定

Main コンテキストと Private コンテキストの 2 つのコンテキストがあります。私はそれらを 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 オブジェクトに障害が発生しているようです。保存する前にスレッド化されたコンテキストでオブジェクトを取得すると、オブジェクトにエラーが発生しないため、一時的な値が保持されます。

4

1 に答える 1

5

最大の力、

トランジェントは非常に単純です。これらは、バッキング ストアには常に存在しないプロパティです。したがって、それらが表示されるのは、子 MOC を使用していて、それらの値を外部から割り当てているためです。トランジェントが常に有効であることを確認するには、、、、およびメソッドの実装-awakeFromInsertを検討する必要があります。-awakeFromFetch-prepareForDeletion-didTurnIntoFault-willTurnIntoFault

アンドリュー

于 2012-11-20T14:50:06.887 に答える