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