2015-12-27 23 views
6

Ho un problema con il recupero di un oggetto dopo l'aggiunta in una relazione. La prima volta che ho recuperato la categoria, ho sempre trovato, quindi quando ho aggiunto alla relazione le seguenti categorie non sono state trovate.Non trovato un oggetto in coredata dopo l'aggiunta a una relazione

La relazione è un Many-To-Many.

Esempio:

  • Fetch categoria con categoryId = 10
  • oggetto categoria Trovato
  • aggiunta alla relazione oggetto padre
  • Prossimo oggetto
  • Se le diverse categorie ha la stessa id, categoryId = 10 , non trovato

    NSManagedObjectContext *private = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
    
        [private setParentContext:self.model.context]; 
        __block NSError *error = nil; 
    
        [private performBlockAndWait:^{ 
    
         GPDeal *deal = [EKManagedObjectMapper objectFromExternalRepresentation:dic withMapping:[GPDeal objectMapping] inManagedObjectContext:private]; 
         for (NSDictionary *dic in responseObject[@"response"]) { 
    
          GPCategory *category; 
    
          //The first time always found 
          if ((category = [GPCategory MR_findFirstByAttribute:@"catId" withValue:dic[@"mainAttribute"] inContext:private])) { 
           NSLog(@"Found"); 
           [category addDealsObject:deal]; 
    
          } else { 
           NSLog(@"Not Found"); 
    
          } 
    
         } 
        }]; 
    
        NSError *PrivateError = nil; 
        if (![private save:&PrivateError]) { 
         NSLog(@"Unresolved error %@, %@", PrivateError, [PrivateError userInfo]); 
         abort(); 
        } 
    
        if (!error) { 
         //Save on main moc 
         [self.model saveWithErrorBlock:^(BOOL success, NSError *error) { 
          if (!success) { 
           NSLog(@"Error saving context: %@\n%@", [error localizedDescription], [error userInfo]); 
          } 
         }]; 
    
        } else { 
         NSLog(@"Error saving context: %@\n%@", [error localizedDescription], [error userInfo]); 
        } 
    

EDIT:

risolto, credo che il mio problema era che ho dimenticato di salvare il contesto principale, alla fine di ogni iterazione.

 NSManagedObjectContext *backgroundMOC = [self.model backgroundMOC:self.model.context]; 

     [backgroundMOC performBlockAndWait:^{ 

      for (NSDictionary *dic in responseObject[@"response"]) { 

       GPDeal *deal = [EKManagedObjectMapper objectFromExternalRepresentation:dic withMapping:[GPDeal objectMapping] inManagedObjectContext:backgroundMOC]; 

       GPCategory *category; 
       if ((category = [GPCategory MR_findFirstByAttribute:@"catId" withValue:dic[@"mainAttribute"] inContext:backgroundMOC])) { 
        NSLog(@"Found with mainAttribute %@", dic[@"mainAttribute"]); 
        [deal addDealCategoryObject:category]; 
       } 

       if([backgroundMOC hasChanges]) { 
        NSError * error; 
        [backgroundMOC save:&error]; 

        [self.model.context performBlockAndWait:^{ 
         if([self.model.context hasChanges]) { 
          NSError * error; 
          [self.model.context save:&error]; 
         } 
        }]; 
       } 
      } 
     }]; 
+0

A quale contesto appartiene l'oggetto 'deal'? Sembra che debba essere un contesto diverso da "privato". Non si dovrebbero impostare relazioni tra oggetti in diversi contesti. Passa il ManagedObjectID e poi recuperalo nel contesto 'private' usando' objectWithID'. – pbasdf

+0

Ho già controllato, ma 'deal' viene creato all'interno del contesto privato – brunobasas

+0

quindi il tuo problema è solo con caregoryId = 10? La prima volta che ne hai 10 in dic [@ "mainAttribute"] trovi la categoria e la seconda volta no? Il fatto che il problema non provenga da MR_findFirstByAttribute mi dice che il problema potrebbe essere la stringa contenente il numero intero in dic [@ "mainAttribute"]. potresti NSLog (@ "ID: -% @ -") per verificare che l'ID non abbia spazi prima o dopo? – Mikael

risposta

1

Potrebbe mancare il salvataggio della catena MOC. Per chiarezza, ho sostituito la parola chiave private con il nome variabile backgroundMOC.

Nella domanda di cui sopra, posso solo supporre che la linea NSManagedObjectContext *private = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; è tecnicamente simile a:

- (NSManagedObjectContext *)backgroundMOC:(NSManagedObjectContext *)mainMOC 
{ 
    NSManagedObjectContext * threadManagedObjectContext = [[NSManagedObjectContext alloc] 
          initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
    [threadManagedObjectContext setParentContext:mainMOC]; 
    [threadManagedObjectContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy]; 
    return threadManagedObjectContext; 
} 

passando self.model.context come mainMOC, con un self.model.context e setMergePolicy.
Analogamente, devo presumere che self.model saveWithErrorBlock è tecnicamente identico a:

[mainMOC performBlockAndWait:^{ 
    if([mainMOC hasChanges]) { 
     NSError * error; 
     [mainMOC save:&error]; 
     // handle error 
    } 
}]; 

tal caso, lo stesso dovrebbe dirsi della (vostra private riferimento) backgroundMOC:

[backgroundMOC performBlockAndWait:^{ 
    if([backgroundMOC hasChanges]) { 
     NSError * error; 
     [backgroundMOC save:&error]; 
     // handle error 
    } 
}]; 

Nell'altra parole, si desidera assicurarsi che l'operazione di salvataggio backgroundMOC e mainMOC venga eseguita dai rispettivi thread, con performBlockAndWait.

+0

puoi guardare il mio ultimo aggiornamento? apprezzo davvero – brunobasas

+0

Di preoccupazione è il thread da cui si esegue 'performBlockAndWait' per' self.model.context save'. Questo dovrebbe essere fatto sul thread principale, altrimenti la tua 'UI' (diciamo che stai usando' NSFetchedResultsController') può bloccarsi (vedi http://stackoverflow.com/a/6913811/218152). Inoltre, se è necessario '[mainMOC save: & error]' ogni volta che si '[backgroundMOC save: & error]', potrebbe non essere necessario un 'backgroundMOC' in primo luogo: l'idea di' backgroundMOC' è di eseguire operazioni lunghe , che potrebbe non essere il caso qui. Maggiori informazioni: http://stackoverflow.com/search?q=user%3A218152+performBlockAndWait – SwiftArchitect