2012-01-20 4 views
6

コアデータロジックをRKManagedObjectStoreに移行して以来、重大な問題があります。 Iビュー・コントローラのメインスレッド内【NSManagedObject managedObjectContext]に設定コンテキストとセットアップNSFetchedResultsController:私はこのようなコンテキストでオブジェクトを挿入Restkit [NSManagedObject managedObjectContext]が異なるインスタンスを返します

assert([NSThread isMainThread]); 
NSManagedObjectContext* context = [NSManagedObject managedObjectContext]; 
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:[Item fetchRequest] managedObjectContext:context sectionNameKeyPath:nil cacheName:@"Master"]; 

Item* item = [Item object]; 
item.name = @"Foo"; 
[[RKObjectManager sharedManager].objectStore save]; 

しかしフェッチ結果コントローラ変更を通知されません。したがって、私は手動で通知を登録:

[[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextDidSaveNotification object:nil queue:nil usingBlock:^(NSNotification *note) { 
    NSLog(@"Context changed"); 

    [self.fetchedResultsController performFetch:nil]; 
    [self.tableView reloadData]; 
}]; 

をRKManagedObjectStoreが異なるコンテキスト間で変更をマージしますので、これは本当に、私は考える必要はありません。第二に、Itemオブジェクトを削除するため、私はこれは、オブジェクトが別のコンテキスト内で削除することができないというエラーが生成

[item deleteEntity]; 

を試してみました。これは明らかに当てはまりますが、WHYメインスレッドのコンテキストと同じではありませんか?私は、エンティティエン削除する前に、ビューコントローラの内部でも、次の呼び出し:

assert([NSThread isMainThread]); 
NSManagedObjectContext* sameContext1 = [NSManagedObject managedObjectContext]; 
NSManagedObjectContext* sameContext2 = self.fetchedResultsController.managedObjectContext; 
assert(sameContext1 == sameContext2); //FAILS 

[NSManagedObject managedObjectContext]を使用しているときに呼び出されRKManagedObjectStoreのmanagedObjectContextゲッターの実装を見てみると、スレッドごとに同じインスタンスが返される必要があります。

-(NSManagedObjectContext*)managedObjectContext { 
    NSMutableDictionary* threadDictionary = [[NSThread currentThread] threadDictionary]; 
    NSManagedObjectContext* backgroundThreadContext = [threadDictionary objectForKey:RKManagedObjectStoreThreadDictionaryContextKey]; 
    ... 
} 

答えて

9

私は最終的に、数時間のデバッグの後でその厄介なバグを追跡しました。問題はRKObjectManagerRKManagedObjectStoreへの参照を保持していることです。しかし、何らかの理由でARCを使用すると、参照が[RKObjectManager sharedManager]インスタンスに保持されず、割り当てが解除されています。そのため、スレッドローカルキャッシュのフラッシュが発生します。したがって、アクセスごとに新しい管理コンテキストが作成されるため、管理対象オブジェクトコンテキストマージは機能しません。修正は簡単です。あなたのApp DelegateのRKManagedObjectStoreへの強力な参照を維持すれば完了です。

関連する問題