簡體   English   中英

NSFetchedResultController未在委托中調用controllerDidChangeContent

[英]NSFetchedResultController not calling controllerDidChangeContent in delegate

在StackOverflow上有很多看起來很相似的問題,但是我問這個是因為幾乎每個現有問題都是由於未在FRC上調用performFetch引起的。

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

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 DOES具有數據。 因此,提取請求正確無誤,下載將記錄放置在正確的位置並正確保存,並且更新屏幕方法能夠獲取這些項目並填充屏幕。

我們這里唯一的問題是未調用委托方法。

這里有我們想念的東西嗎? 就像我說的那樣,我們在一些地方使用了相同的模式,並且有效。 只是在這種情況下它不起作用。

讓我知道您是否還想查看其他代碼,如果可以的話,我會通過。

發生的情況是您正在使用其他NSManagedObjectContext保存下載的數據。 如您所說,該上下文使用后台隊列。 但是,這種情況可能不是FRC的背景。 在這種情況下,您需要合並到主上下文中,以偵聽其他更改的通知。

但是,解決此問題的簡單方法是使用作為主要上下文子級的背景上下文。 也就是說,創建一個類型為privateQueue的新上下文,並將其parentContext設置為等於當前上下文。

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

好的,經過一些認真的調試,我們終於找到了導致此問題的原因,這很麻煩。

因此,我所質疑的代碼存在於一個classclass本質上是工廠類的“工人”。

工廠使用了該工人來創建對象,並將其返回給工廠的所有者(如果需要,可以稱為“消費者”)。

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

雖然我們一直對Factory保持強烈的引用,但是工廠實際上並沒有在其使用的功能之外存儲對worker的引用。

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

因此,簡單的解決方法是將存儲的引用添加到工作程序。

較長的修復方法是重構我認為的某些代碼,但這是另一天的工作。

感謝您的所有幫助。 它無疑幫助我們消除了問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM