2013-03-07 34 views
8

Tamam, bu beni deli ediyor.NSMergeConflict (iki iş parçacığı) - birleştirme ilkesi ayarlandığında

UImanageddocument kullanan iki iş parçacığım var, biri kullanıcının seçtiği ana bağlamda, kendi moc ile arka plan iş parçacığı verileri zaman damgalarına göre bir sunucuyla eşitler. 1. Bundan yine aynı nesneyi değiştirmek için 4. deneyin arka plandan arka planda ana bağlamına 3. Kaydet 2. Senkronize bir nesneyi ekleyin: Ben ne zaman

Tüm ancak iyi çalışıyor gibi görünüyor ana bağlam - ana iş parçacığı

bir NSMergeConflict

ben bağlamları başlatmak nasıl göstermek için, alakasız kodu bir sürü hariç benim bazı kod eklemek için gidiyorum olsun, umarım birileri beni aydınlatmak. Bu alanlarda temel verilerin zor olduğunu biliyorum.

(applicationdidfinishloadingwithoptions olarak) ana iş parçacığı üzerinde

:

NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] lastObject]; //get the default user documents folder 
    url = [url URLByAppendingPathComponent:DATABASENAME]; 
    UIManagedDocument *doc = [[UIManagedDocument alloc] initWithFileURL:url]; 
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: 
          [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, 
          [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]; 
    doc.persistentStoreOptions = options; 
    [doc.managedObjectContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy]; 
    self.database=doc; 
    self.mainManagedObjectContext=self.database.managedObjectContext; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDataModelChange:) name:NSManagedObjectContextObjectsDidChangeNotification object:self.database.managedObjectContext]; 

Ve daha sonra: Ben birleştirme her türlü denedim

dispatch_queue_t fetchQ = dispatch_queue_create("syncing list", NULL); 
dispatch_async(fetchQ,^ // *********** BACKGROUND THREAD *********** 
{ 
    AppDelegate *delegate = (AppDelegate*)[UIApplication sharedApplication].delegate; 
    NSManagedObjectContext *backgroundMOC2; 
    backgroundMOC2=[[NSManagedObjectContext alloc] init]; 
    [backgroundMOC2 setPersistentStoreCoordinator:delegate.mainManagedObjectContext.persistentStoreCoordinator]; 
    [backgroundMOC2 setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy]; 
    [delegate.mainManagedObjectContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy]; 
    [[NSNotificationCenter defaultCenter] addObserver:delegate.mainManagedObjectContext selector:@selector(mergeChangesFromContextDidSaveNotification:) name:NSManagedObjectContextDidSaveNotification object:backgroundMOC2]; 


    ** pseudo-code: 
     perform fetch request from CD 
     submit data to server with POST request (synchronously) 
     retrieve JSON reply from server 
     update what's needed in CD objects 
    ** end of pseudo code 

    [backgroundMOC2 save:nil]; 
    [[NSNotificationCenter defaultCenter] removeObserver:delegate.mainManagedObjectContext name:NSManagedObjectContextDidSaveNotification object:backgroundMOC2]; 
    }); 
dispatch_release(fetchQ); 

:

- (void)handleDataModelChange:(NSNotification *)note 
{ 
    [self save]; 
} 

-(void) save 
{ 
     [self.database saveToURL:self.database.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:^(BOOL success) { 
      batch_save=!success; 
      NSLog(@"save success %d",success); 
     }]; 
} 

Ve arka plan iş parçacığı üzerinde

politika sabitleri boşuna.

bu soruyla ve dosya kaydedilmedi:

conflictList = ( "NSMergeConflict (0x1a9ee1e0) OldVersion ile objectId '0x9dcec90' ile NSManagedObject (0x119aea80) için = 10 ve newversion = 11 ve eski nesne snapshot = {\ n displayName = \ "\"; \ n machineName = KIYGRDRTTDVLTQB; \ n note = \ "\"; \ n ürün = \ "0x11967ab0 \"; \ n public = 1; \ n yayınladı = 1; \ n quantity = 3; \ n registeredTo = \ "\"; \ n registeredToEmail = \ "\"; \ n registeredToNote = \ "\"; \ n status = \ "REGISTRY \"; \ n upDate = \ "2013-03-07 10:22:01 +0000 \"; \ n wishList = \ "\"; \ n} ve yeni önbelleğe alınmış satır = {\ n displayName = \ "\"; \ n machineName = KIYGRDRTTDVLTQB; \ n note = \ "\"; \ n ürün = \ "0x1a9ee3d0 \"; \ n pub lic = 1; \ n yayınlandı = 1; \ n miktar = 3; \ n registeredTo = \ "\"; \ n registeredToEmail = \ "\"; \ n registeredToNote = \ "\"; \ n status = \ "ON REGISTRY \ "; \ n upDate = \" 2013-03-07 10:22:03 +0000 \ "; \ n wishList = \" \ "; \ n}" ); }

BTW, eski ve yeni nesneler arasında gördüğüm tek fark "ürün" için bir göstericidir. Bu benim sorunum olabilir mi?

Bir başka olası ipucu, bunun yalnızca yeni nesneler eklendiğinde gerçekleşmesi ve yalnızca arka plan senkronizasyonundan sonra gerçekleşmesidir. Uygulamayı durdurup yeniden yüklediğimde (kalıcı deposu yeniden yüklediğimde), şimdi varolan nesneyi sorun olmadan düzenleyebilir ve sorunsuz olarak istediğim sıklıkta değiştirebilirim.

Teşekkürler çocuklar

cevap

19

Tamam arkadaşlar, bunun üzerinde fikrimi kırma bir ay sonra

- ben tahmin ediyorum bir çözüm ve hiçbir şey yoktur. Aslında Apple ile bir destek olayı açtım ve bunu çözdüler.

Yani burada gider:

ana yönetilen nesne bağlamı için birleştirme politikası belirlemek, parentContext denilen bir özellik vardır. Belgelerin bu konuda kıt olduğu için bu mülkün ne olduğu hala bana açık değil. Ancak bu kesinlikle MY problemimi çözmektedir. Lütfen benim iş akışımda bir NSManagedDocument oluşturup içeriği buradan ayıkladığımı göz önünde bulundurun. Bence çoğu insan bunu tersine yapar (çoğu yönetilen belgeyi kullanmaz).

yerine

[self.mainManagedObjectContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy]; 

Şimdi kullanın:

NSManagedObjectContext *parentContext = delegate.mainManagedObjectContext.parentContext; 
    [parentContext performBlockAndWait:^{ 
     [parentContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy]; 
    }]; 

blok şey, bu doğru iplik yapılır emin olmak için bir önlem, önemli olan bir birleştirme politikasını belirlemeye İstenen bağlamın parentContext.

Kişisel bir notta, iki büyük boos eklemeliyim: 1. Gömülü bir örnek olmasına rağmen NSManagedDocument'i kullanmak benim için iyi. 2. Alandaki belgelerin eksik olması için Apple'dan Büyük boo. ManagedObjectContexts hakkında haftalar geçirdim ve bugün parentContext özelliği ile ilk tanışmam oldu.

+0

merhaba @ llan lewin, http://stackoverflow.com/questions/19443853/nsmergeconflict-for-nsmanagedobject-with-single-managedobjectcontext – Ranjit

+0

Her şeyden önce lütfen teşekkürler! Bu kesinlikle sorunumu çözer. Üst bağlamda, bunları şu adresten okuyabilirsiniz: https://developer.apple.com/library/ios/documentation/DataManagement/Conceptual/UsingCoreDataWithiCloudPG/UsingCoreDataWithiCloudPG.pdf (bölüm: Yönetilen Belge'nin Yönetilen Nesne Bağlamını Kullanma.) –

+0

Merhaba Ilan, cevabınızda bu yaklaşımı belirttiniz (örn. PerformBlockAndWait'te birleştirme ilkesi belirleme), NSManagedDocument öğesi oluşturarak içeriği aldığınızda kullanışlıdır. Bu iş akışını kullanmıyorum. Bunu iş akışımda da eklemeliyim mi? OR başka bir yol var mı? – Arun