2011-12-23 48 views
2

我在我的應用程序中有一個操作,它需要一個很大的,有時幾秒更新的核心數據。因爲我想做的不僅僅是展示一個微調器,我還想向最終用戶顯示一個進度條。然而,這提出了一些問題,因爲Core Data堅持在主線程上運行。我曾嘗試將核心數據放在後臺線程上,結果爲dispatch_async。問題是UIKit也想在主線程上運行,更糟糕的是,只有在當前線程結束後更新它。這會導致進度條只有在完成所有處理之後纔會更新!如何更新UI以顯示Core Data長時間運行的進程?

如何更新UI並安全地更新我的數據?

NSArray* items = [[response.data objectForKey:@"result"] objectForKey:@"items"]; 

NSManagedObjectContext* context = [RBGameItemController sharedInstance].managedObjectContext; 

int itemCount = [items count]; 

for (int i = 0; i < itemCount; i++) { 
    float progress = ((float)i/(float)itemCount)*0.95f; 
    self.progressView.progress = 0.5f + progress; 

    id item = [items objectAtIndex:i]; 
    [GameItem gameItemFromDictionary:item inManagedObjectContext:context]; 
} 

NSError* error = nil; 
[context save:&error]; 

回答

1

核心數據不需要在主線程上工作,只需要爲每個單獨的線程都有一個NSManagedObjectContext。在單獨的線程上使用相同的後備存儲創建一個新的NSManagedObjectContext(使用NSOperationQueue)並在那裏進行處理。從備用線程保存NSManagedObjectContext後,主線程的上下文將從後備存儲區中選取更改。要從備用線程更新UI,請使用

- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait; 

這是NSObject上的方法。如果有什麼不清楚的話,祝你好運和評論。

+0

我在發佈之前嘗試過,但發現錯誤,說我無法從其他managedObjectContext中刪除對象。 – 2011-12-23 19:38:50

+0

在上下文之間傳遞NSManagedObjects時會導致該錯誤。如果您在備用線程的上下文下工作,則必須在該上下文中查找要修改的對象 - 每個線程必須完全分開。你可以分享的唯一東西是後臺商店。 – 2011-12-23 19:56:48

+0

這是將它放在後臺線程上的問題。我修改了代碼以接受一個上下文作爲參數,並傳遞了在我的'dispatch_async'塊中創建的新代碼。然後我在主線程上創建了一個新的GCD線程來更新UI。像魅力一樣工作! :D – 2011-12-23 20:22:54

相關問題