2012-05-02 122 views
1

我的iOS應用程序在掛起時停留在兩次屏幕之間幾次。 它屬於存儲數據,但這只是凍結而沒有錯誤。 有人任何想法如何我可以解決這個問題?我的iOS應用程序在保存多線程時掛起

self.fetchF = dispatch_queue_create(label, NULL); 
dispatch_async(self.fetchF, ^{ 

    NSArray *feeds = [FeedFetcher getData:self.pageTitle downloadBy:@"up"]; 

    NSManagedObjectContext *newContext = self.managedObject; 

    for (NSDictionary *feedInfo in feeds) { 
     [Feed FeedWithInfo:feedInfo InManageObject:newContext]; 
    } 

    dispatch_async(dispatch_get_main_queue(), ^{ 

     NSError *error = nil; 
     if (newContext != self.managedObject) 
      [newContext save:&error]; 

     if (error) 
      NSLog(@"Error save : %@", error); 

     [self setupFetchedResultsController]; 

     [self downloadImages:feeds]; 
    });   
}); 

編輯:

我改變我的managedobjectcontext所以它的每個線程一個新的。 但現在當我在兩個屏幕之間延續幾次它凍結[self.fetchedResultsController performFetch:& error];沒有錯誤.. 有人有解決方案的想法嗎?

- (void)performFetch 
{ 
    if (self.fetchedResultsController) { 
     if (self.fetchedResultsController.fetchRequest.predicate) { 
      if (self.debug) NSLog(@"[%@ %@] fetching %@ with predicate: %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), self.fetchedResultsController.fetchRequest.entityName, self.fetchedResultsController.fetchRequest.predicate); 
     } else { 
      if (self.debug) NSLog(@"[%@ %@] fetching all %@ (i.e., no predicate)", NSStringFromClass([self class]), NSStringFromSelector(_cmd), self.fetchedResultsController.fetchRequest.entityName); 
     } 
     NSError *error; 
     if (self.fetchedResultsController != nil) 
      [self.fetchedResultsController performFetch:&error]; 

     if (error) NSLog(@"[%@ %@] %@ (%@)", NSStringFromClass([self class]), NSStringFromSelector(_cmd), [error localizedDescription], [error localizedFailureReason]); 
    } else { 
     if (self.debug) NSLog(@"[%@ %@] no NSFetchedResultsController (yet?)", NSStringFromClass([self class]), NSStringFromSelector(_cmd)); 
    } 
    [self.tableView reloadData]; 
} 
+0

你確定你是在創建線程中使用上下文嗎? – HeikoG

+0

我在應用程序委託類中創建它。我把它交給我必須使用的課程。每次我使用NSManagedObjectContext * newContext = self.managedObject; –

回答

2

核心數據通常不是線程安全的。經驗法則是每個線程創建一個NSManagedObjectContext。我相信你在線程中重複使用你的上下文,這就是問題所在。

Google文檔核心數據併發:

核心數據使用線程(或序列化隊列)約束,以保護 管理對象和管理對象上下文(請參閱「併發性 核心數據」)。這樣做的結果是上下文假定默認所有者是分配它的線程或隊列 - 這是由調用其init方法的線程決定的 。你不應該,因此 ,初始化一個線程上下文然後將它傳遞到 不同的線程。相反,您應該傳遞對持久存儲協調器的引用,並讓接收線程/隊列創建一個新的從上面導出的上下文 。如果使用NSOperation,則必須在main(對於串行隊列)或start(對於併發 隊列)中創建 上下文。

+0

謝謝你的作品:) –

相關問題