2012-01-20 3 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]; 

그러나 페치 결과 제어기 변경 사항에 대한 알림을받지 못합니다. 따라서 나는 수동으로 알림 등록 : RKManagedObjectStore가 다른 컨텍스트에서 변경 내용을 병합 이후

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

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

정말, 내가 생각하는 필요는 없습니다. 둘째, 시도한 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에 대한 강력한 참조 만하면됩니다.

관련 문제