2013-10-29 15 views
6

Sto riscontrando problemi con un semplice salvataggio di dati su una singola applicazione con thread dopo che due righe sono state riordinate.iOS7 NSMergeConflict su thread singolo Salva

Sono riuscito a semplificare la codifica per riprodurre l'errore e apprezzerei un secondo parere con qualcun altro che stava provando a farlo.

Si tratta di un controllo di integrità come io sono sospettoso di una questione centrale dei dati introdotto con iOS 7 come questo ha funzionato bene in iOS 6.

In primo luogo, avviare un nuovo progetto di dati di base e creare questo modello .. .

simple core data model

attributo 'corrente' è un booleano opzionale. La relazione uno-a-molti è una relazione ordinata, creando un NSOrderedDataset.

Ora aggiungi un paio di pulsanti all'app; il primo per creare i dati (un progetto e due 'disegni' associati) e il secondo per scambiare i due disegni, quindi impostare una proprietà all'interno del primo disegno.

Ecco il codice ...

-(IBAction)onTestButton:(id)sender 
{ 
    id delegate = [[UIApplication sharedApplication]delegate]; 
    NSManagedObjectContext *managedObjectContext = [delegate managedObjectContext]; 

    self.project = [NSEntityDescription insertNewObjectForEntityForName:@"Project" inManagedObjectContext:managedObjectContext]; 
    Drawing *drawing1 = [NSEntityDescription insertNewObjectForEntityForName:@"Drawing" inManagedObjectContext:managedObjectContext]; 
    Drawing *drawing2 = [NSEntityDescription insertNewObjectForEntityForName:@"Drawing" inManagedObjectContext:managedObjectContext]; 

    NSMutableOrderedSet* tempSet = [NSMutableOrderedSet orderedSetWithOrderedSet:self.project.drawings]; 
    [tempSet addObject:drawing1]; 
    [tempSet addObject:drawing2]; 
    self.project.drawings = tempSet; 

    [self save]; 
} 

-(IBAction)onTestButton2:(id)sender 
{ 
    NSMutableOrderedSet *exchange = [self.project mutableOrderedSetValueForKey:@"drawings"]; 
    [exchange exchangeObjectAtIndex:0 withObjectAtIndex:1]; 
    self.project.drawings = exchange; 

    [self save]; 

    Drawing *drawing = [self.project.drawings objectAtIndex:0]; 

    BOOL current = [drawing.current boolValue]; 
    drawing.current = [NSNumber numberWithBool:!current]; 

    [self save]; 
} 

-(void)save 
{ 
    id delegate = [[UIApplication sharedApplication]delegate]; 
    NSManagedObjectContext *managedObjectContext = [delegate managedObjectContext]; 
    NSError *error = nil; 

    if(![managedObjectContext save:&error]) 
    { 
     NSLog(@"%@ Save: Unresolved Error on Save %@", error, [error userInfo]); 
     abort(); 
    } 
} 

Ora, test premendo il primo pulsante di prova. Questo imposta i dati.

Quindi premere il secondo pulsante di test .... tutto OK !!!

Ora premere il secondo pulsante di test di nuovo e BANG. Si 'dovrebbe ottenere un errore di NSMergeConflict simile a questo ....

Salva: Errore non risolto su Save { conflictList = ( "NSMergeConflict (0x8a7d0b0) per NSManagedObject (0x8bedfa0) con objectID '0x8bd9340 ' con oldVersion = 1 e newVersion = 2 e snapshot oggetto vecchio = {\ n
current = \ "\"; \ n project = \ "0x8bc3f50 \"; \ n} e nuova riga memorizzata nella cache = {\ n current = \ "\"; \ n project = \ "0x8aa88c0 \"; \ n} " );

Ho notato dall'errore che il mio oggetto Progetto è cambiato. Tuttavia, questa è un'applicazione a thread singolo che utilizza il contesto dell'app principale.

Ho speso troppo tempo su questo e apprezzerei che qualcun altro passasse commenti su dove si trovasse il problema. Si tratta di un bug dei dati di base, o sono un vero "pazzo"?

Molte grazie

/Fitto

+0

Quale dei 'chiamate save' in' onTestButton2' causa l'errore? –

+0

Il secondo. È sempre dopo aver provato a cambiare i dati dopo lo 'scambio' salvato. – Fittoburst

+0

Posso riprodurlo, ma non so davvero che il wtf lo stia causando. –

risposta

9

ho avuto problemi simili un trovato una soluzione qui:

http://prod.lists.apple.com/archives/cocoa-dev/2013/Oct/msg00657.html

In breve - aggiungere questo per la configurazione MOC:

[_managedObjectContext setMergePolicy:[[NSMergePolicy alloc] initWithMergeType:NSMergeByPropertyObjectTrumpMergePolicyType]]; 

Questo riguarda OS X 10.9 Mavericks as wel l quando si utilizza NSSQLStoreType.Non è stato possibile ripetere l'errore Unisci utilizzando NSXMLStoreType.

Per 2.x Swift

managedObjectContext.mergePolicy = NSMergePolicy(mergeType: .MergeByPropertyObjectTrumpMergePolicyType) 
+0

Grazie, sì che lo risolve. Accidenti! Non sono sicuro del motivo per cui sta accadendo. Posso solo supporre che i dati di base stiano eseguendo salti mortali "invisibili" dietro le quinte. – Fittoburst

+0

Non capisco davvero perché, ma questo sembrava risolvere il mio problema di arresto anomalo con AFIncrementalStore. Grazie mille! Sono stati debugging per giorni. – lari

+0

Phewww ... grazie per avermi salvato la vita :) – GKK