2016-12-21 92 views
0

在StackOverflow上有很多非常相似的問題,但我這樣問,因爲幾乎所有存在的問題都是由於在FRC上不調用performFetch造成的。NSFetchedResultController在委託中沒有調用controllerDidChangeContent

在這種情況下,我們稱之爲它。

fetchedResultsController = NSFetchedResultsController(fetchRequest: StepRecord.fetchRequest(forDate: date), 
               managedObjectContext: theMainThreadContext, 
               sectionNameKeyPath: nil, 
                 cacheName: nil) 

fetchedResultsController.delegate = self 

do { 
    try fetchedResultsController.performFetch() 
} catch (let error) { 
    print(error) 
} 

然後在後面的功能,我們有這樣的事情......

func updateScreen() { 
    if fetchedResultsController.fetchedObjects.count == 0 { 
     // download data and store into core data 
    } 

    // update the screen 
} 

,我們有委託方法...

func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { 
    updateScreen() 
} 

被寫入到地方核心數據肯定是寫入到backgroundThreadContext(這是我們在應用程序中多次使用的模式,它在別處工作)。

但是,委託方法在這種情況下不會被調用。

如果我們退出屏幕並返回updateScreen方法運行並且FRC有數據。因此,提取請求是正確的,下載將記錄放在正確的位置並正確保存,並且更新屏幕方法能夠獲取這些項目並填充屏幕。

我們在這裏遇到的唯一問題是委託方法沒有被調用。

有什麼我們錯過了嗎?就像我說過的,我們在一些地方使用了相同的模式,它的工作原理。只是在這種情況下,它不起作用。

讓我知道是否有任何其他代碼,你想看看,如果可以的話,我會通過它。

+0

@ SeanLintern88 AFAIK'controllerDidChangeContent'還包含附加內容,因此在獲取請求中添加數據應該觸發委託方法。 – Fogmeister

+0

所以你說,即使初始數據爲空,添加的數據應該會導致更新?如果是這樣你可以發佈獲取請求:D'StepRecord.fetchRequest(forDate:date)' – SeanLintern88

+0

@ SeanLintern88是的它是如何工作的。最終得到它的工作。謝謝 – Fogmeister

回答

0

發生什麼事是您正在使用不同的NSManagedObjectContext來保存下載的數據。正如你所說,這個上下文使用了一個後臺隊列但也許這種背景不是FRC背景下的孩子。在這種情況下,您需要合併到聽取其他更改的通知的主要上下文中。

但修復它的簡單方法是使用背景上下文,它是主要上下文的子節點。也就是說,創建一個類型爲privateQueue的新上下文,並將其parentContext設置爲等於當前上下文。

+0

是的,這就是我們正在做的。但我會仔細檢查。謝謝 – Fogmeister

+0

請記住,如果您使用的是NSPersistentContainer並使用newBackgroundContext,則該上下文不是viewContext的子集。他們不會自動合併。 – Gabriel

+0

嘿,所以我們最終發現了一個嚴重的調試會話後的問題。我添加了一個答案。謝謝您的幫助 :) – Fogmeister

0

TL:DR - 不存在的對象不會偵聽NSNotifications。

好的,經過一番嚴肅的調試後,我們終於找到了導致這個問題,這是一個愚蠢的。

因此,我的問題中的代碼存在於一個class內部,它基本上是工廠類的「工人」。

此工人被工廠用來創建一個對象並將其返回給工廠所有者(如果您喜歡,則爲「消費者」)。

Consumer        - view controller 
- Factory        - strongly referenced 
    - Worker       - function variable 
     - FetchedResultsController stuff - strongly referenced 

雖然我們保持強大的參考廠方,實際上並沒有存儲到工人的引用它在使用功能之外。

這意味着當下載完成並將內容保存到CoreData中時,Fetched Results Controller和「worker」實際上不再存在於內存中。

所以,簡單的修復就是向工作人員添加存儲的引用。

更長的修復是重構一些我認爲的代碼,但這是另一天的工作。

感謝您的幫助。這無疑幫助我們解決了這個問題。

相關問題