2012-01-20 20 views
6

Ho seri problemi da quando ho migrato la mia logica dei dati di base in RKManagedObjectStore. I ha installato una NSFetchedResultsController con il contesto impostato [NSManagedObject managedObjectContext] all'interno il filo principale del controller di vista:Restkit [NSManagedObject managedObjectContext] restituisce istanze diverse

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

poso oggetti nel contesto come questo:

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

Ma il controllore risultati recuperato non viene informato delle modifiche. Così ho registrato una notifica manualmente:

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

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

Questo non dovrebbe davvero essere necessario a mio avviso, dal momento che RKManagedObjectStore fonde modifiche in diversi contesti. In secondo luogo, per l'eliminazione dell'oggetto Item ho provato

[item deleteEntity]; 

Questo ha prodotto un errore che dice che l'oggetto non può essere eliminato in un altro contesto. Questo è ovviamente vero, ma WHY l'inferno è il contesto non è la stessa istanza per il thread principale? Chiamo il seguente anche all'interno del controller della vista poco prima di eliminare en entità:

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

Guardando managedObjectContext Attuazione getter del RKManagedObjectStore che viene chiamata quando si usa [NSManagedObject managedObjectContext], la stessa istanza per filo deve essere restituito:

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

risposta

9

Alla fine ho rintracciato quel brutto baco dopo ore di debug. Il problema è che RKObjectManager contiene un riferimento a RKManagedObjectStore. Ma in qualche modo quando si usa ARC quel riferimento non viene mantenuto nell'istanza [RKObjectManager sharedManager] e viene deallocato. Ciò provoca lo svuotamento della cache locale del thread. Pertanto la fusione del contesto dell'oggetto gestito non funziona perché su ogni accesso viene creato un nuovo contesto gestito. La correzione è facile. Mantieni un forte riferimento allo RKManagedObjectStore nel tuo delegato dell'app e il gioco è fatto.

Problemi correlati