2012-05-01 61 views
4

我想在後臺下載一些JSON對象,並且正在做相當多的多線程。一旦操作完成後,我注意到,這個斷言失敗:iPhone iOS如何合併核心數據NSManagedObjectContext?

NSAssert([user.managedObjectContext isEqual:[AppUser managedObjectContext]],@"Different contexts"); 

如何合併變爲由[APPUSER managedObjectContext]定義的主要方面?

+0

請包括代碼,你完成操作並嘗試合併。你是否遵循https://developer.apple的指導原則。com/library/mac/ipad/#documentation/Cocoa/Conceptual/CoreData/Articles/cdConcurrency.html#// apple_ref/doc/uid/TP40003385-SW1(核心數據併發,萬一鏈接不起作用) – jrturton

回答

0

在我的情況下,我使用RKObjectLoader的子類,並且有太多的線程和操作來跟蹤發生了什麼。我發現可以很好地要求RKObjectStore通過請求加載的對象保存自己來爲我合併更改。 (我問[AppUser managedObjectContext]自救,這是以前錯誤

正確的解決方案涉及要求加載的對象本身保存在自己的上下文如下:

- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects { 

    AppUser* user = nil; 
    for (id object in objects) 
    { 
     user = object; 
    } 
    NSError* error = nil; 


/**this call fires the:  
// - (void)mergeChanges:(NSNotification *)notification 
within the rkmanagedobjectstore class and merges changes made in this background operation over to the main contxt 
*/ 
[[user managedObjectContext] save:nil]; 

} 
11

我真的建議你閱讀下面的鏈接importing-and-displaying-large-data-sets-in-core-data作者:Marcus Zarra

當您處理線程時,您創建的每個線程都需要具有自己的上下文,如鏈接中所寫的那樣,其中提供的鏈接是jrrtton。然後,如果你要合併主上下文(你在主線程創建的)和其他方面(你在上下文中使用的)之間的變化,你需要在主線程監聽NSManagedObjectContextDidSaveNotification

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextHasChanged:) name:NSManagedObjectContextDidSaveNotification object:nil]; 

和執行合併喜歡

- (void)contextHasChanged:(NSNotification*)notification 
{ 
    if ([notification object] == [self mainObjectContext]) return; 

    if (![NSThread isMainThread]) { 
    [self performSelectorOnMainThread:@selector(contextHasChanged:) withObject:notification waitUntilDone:YES]; 
    return; 
    } 

    [[self mainObjectContext] mergeChangesFromContextDidSaveNotification:notification]; 
} 

通知對象包含您在線程上下文中所做的更改。

的一些注意事項

線程是很難實現的。我提供的鏈接使用NSOperation及其上下文。這個設置非常簡單,但是從iOS 5開始,有一些功能讓您的生活更輕鬆。

例如創建在不同的線程上下文,你可以做如下所示:

// create a context with a private queue so access happens on a separate thread. 
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
// insert this context into the current context hierarchy 
context.parentContext = context; 
// execute the block on the queue of the context 
[context performBlock:^{ 

     // do your stuff (e.g. a long import operation) 

     // save the context here 
     // with parent/child contexts, saving a context pushes the changes out of the current context 
     NSError* error = nil; 
     [context save:&error]; 
}]; 

除了可以看到該文檔爲UIManagedDocument。這個類很好地集成了Core Data,並且可以避免使用Core Data堆棧。

希望它有幫助。

+1

「context.parentContext = context」是什麼意思? – onmyway133

1

您的特殊情況(在後臺下載JSON)很常見。我已經看到了許多沒有多個上下文的實現。

在很多情況下,最簡單也是迄今爲止最魯棒的方法是讓下載的對象通過協議或完成下載的通知通知主線程。然後您在主線程上進行保存。

相關問題