2010-03-08 1 views
7

Ho un problema in cui sto aggiornando una relazione molti-a-molti in un thread in background, che funziona bene in quella minaccia, ma quando rimando l'oggetto al principale thread le modifiche non mostrano. Se chiudo l'app e riapro i dati vengono salvati correttamente e le modifiche vengono visualizzate nel thread principale. Anche l'utilizzo di [blocco del contesto] invece di un diverso contesto dell'oggetto gestito funziona correttamente.Sincronizzazione thread contesto oggetto gestito di dati di base

ho provato NSManagedObjectContext:

- (BOOL)save:(NSError **)error; 
- (void)refreshObject:(NSManagedObject *)object mergeChanges:(BOOL)flag;  

in fasi differenti durante il processo ma non sembrano aiutare.

mio codice dei dati di base utilizza la seguente getter per garantire eventuali operazioni sono sicuri filo:

- (NSManagedObjectContext *) managedObjectContext 
{ 

    NSThread * thisThread = [NSThread currentThread]; 
    if (thisThread == [NSThread mainThread]) 
    { 
     //Main thread just return default context 
     return managedObjectContext; 
    } 
    else 
    { 
     //Thread safe trickery 
     NSManagedObjectContext * threadManagedObjectContext = [[thisThread threadDictionary] objectForKey:CONTEXT_KEY]; 
     if (threadManagedObjectContext == nil) 
     { 
      threadManagedObjectContext = [[[NSManagedObjectContext alloc] init] autorelease]; 
      [threadManagedObjectContext setPersistentStoreCoordinator: [self persistentStoreCoordinator]]; 
      [[thisThread threadDictionary] setObject:threadManagedObjectContext forKey:CONTEXT_KEY]; 
     } 

     return threadManagedObjectContext; 
    } 
} 

e quando passo oggetto tra thread sto usando

-(NSManagedObject*)makeSafe:(NSManagedObject*)object 
{ 
    if ([object managedObjectContext] != [self managedObjectContext]) 
    {    
     NSError * error = nil; 
     object = [[self managedObjectContext] existingObjectWithID:[object objectID] error:&error]; 

     if (error) 
     { 
      NSLog(@"Error makeSafe: %@", error); 
     } 
    } 

    return object; 
} 

Qualsiasi aiuto apprezzato

+0

Modifica: mi sono perso che stavi usando threadDictionary in precedenza. – Wendel

risposta

9

Se si salva il contesto di sfondo sul thread in background e si ascolta NSManagedObjectContextObjectsDidChangeNotification nella thread principale, è possibile chiamare -mergeChangesFromContextDidSaveNotification: in contesto principale (sul thread principale) e le modifiche verranno visualizzate non appena si esegue il salvataggio sul thread in background.