切换选项卡时未调用 NSFetchedResultsControllerDelegate 方法

Posted

技术标签:

【中文标题】切换选项卡时未调用 NSFetchedResultsControllerDelegate 方法【英文标题】:NSFetchedResultsControllerDelegate method not called when switching tab 【发布时间】:2020-04-14 01:01:28 【问题描述】:

我的应用程序有两个标签栏。第一个展示了在视图控制器上添加的游戏列表,并将它们保存在核心数据数据库中。打开第二个选项卡/视图会从数据库中读取数据并将其呈现在表视图中。我实现了NSFetchedResultsControllerDelegatewith 一个 fetch 方法。但是,每当我在第一个选项卡的上下文中添加或插入一个项目并切换到第二个选项卡时,都不会调用 FRC 委托方法。但是当我在第一个选项卡上实现相同的方法时,我可以看到它们在我对数据库进行更改时被调用。

    import UIKit
    import CoreData

    class AllWLeagueController : UITableViewController 

        var fetchRequestController : NSFetchedResultsController<GameMo>!
        var arrayOfGamesModel : [[GameMo]]? = []
        var gameMo: GameMo?
        var gamesMo: [GameMo] = []


        override func viewDidLoad() 
            validation(object: arrayOfGamesModel)

        

        override func viewWillAppear(_ animated: Bool) 
            super.viewWillAppear(animated)
            fetchRequest()
        



        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 


            return arrayOfGamesModel?.count ?? 0
        
        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 



            if let weekL = arrayOfGamesModel?[indexPath.row] 
                if let cell = tableView.dequeueReusableCell(withIdentifier: "WL") as? AllWLeaguesTableViewCell 
                    let winCounts = WLManager.winCountMethod(from: weekL)
                    let lossCounts = WLManager.lossCountMethod(from:weekL)
                    cell.setOulet(win: winCounts, loss: lossCounts, rankName: rankString)

                    cellLayer(with: cell)
                    return cell
                
            

   



  extension AllWLeagueController: NSFetchedResultsControllerDelegate 

        func fetchRequest ()  
            let fetchRequest = NSFetchRequest<GameMo>(entityName: "Game")

            fetchRequest.sortDescriptors = [NSSortDescriptor(key: "win", ascending: true)]

            if let appDelegate = (UIApplication.shared.delegate as? AppDelegate)
                let context = appDelegate.persistentContainer.viewContext

                // fetch result controller
                fetchRequestController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
                fetchRequestController.delegate = self

                do
                    try fetchRequestController.performFetch()

                    if let fetchedObjects = fetchRequestController.fetchedObjects 
                        gamesMo = fetchedObjects


                        print("Fetech Request Activated")
                        print(gamesMo)
                    
                catch
                    fatalError("Failed to fetch entities: \(error)")
                
            

        


        func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) 
            print("TableView beginupdates")
            tableView.beginUpdates()
        

        func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) 
            switch type 
            case .insert:
                if let newIndexPath = newIndexPath 
                    print("insert")
                    tableView.insertRows(at: [newIndexPath], with: .fade)

                
            case .delete:
                if let indexPath = indexPath 
                     print("delete")
                    tableView.deleteRows(at: [indexPath], with: .fade)
                
            case .update:
                if let indexPath = indexPath 
                     print("update")
                    tableView.reloadRows(at: [indexPath], with: .fade)

                

            default:
                tableView.reloadData()
            

            if let fetchedObjects = controller.fetchedObjects 
                gamesMo = fetchedObjects as! [GameMo]

            
        


        func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) 
            print("TableView endupdates")
            tableView.endUpdates()
        
     

【问题讨论】:

你没有在你的问题中提到它,但是,为了仔细检查,你是否在两个视图控制器中使用相同的上下文,你是否保存了你的上下文?或许如果您发布两个控制器的关键部分,我们可以提供更多帮助。 是的,我使用相同的上下文(只有一个)。 您能说明AllWLeagueController 的创建方式和位置吗? 完成。我从 AllWLeagueController 添加了代码。 【参考方案1】:

看起来您的fetchedResultsController 正在更新gamesMo,但您的tableView 正在查看arrayOfGamesModel。但是arrayOfGamesModel 永远不会更新。

您可以更改 tableView 方法以查看 gamesMo,或更改您的 fetchedResultsController 以更新 arrayOfGamesModel

【讨论】:

我将 tableView 方法更改为查看 gamesMo 而不是 arrayOfGamesModel,当我将记录插入上下文时仍然不调用 FRC 委托方法。当我切换到第二个选项卡时,唯一被调用的方法是 fetchRequest。我可以在调试器上看到 print("Fetech Request Activated")。 我用下面的代码arrayOfGamesModel?.append(gamesMo)更新了controller(_:didChange:at:for:newIndexPath:)方法,我可以看到tableView Begin Updates print语句只有在添加之后数据库的第二个项目。它没有检测到插入。 我明白了。我们需要查看更新后的代码,以及第一个控制器的代码以查看发生了什么。由于这使我们远离了当前问题(代码显示UITableViewFRC 断开连接),我建议将您的后续问题作为一个新问题。 完成。链接是:***.com/questions/61233538/…

以上是关于切换选项卡时未调用 NSFetchedResultsControllerDelegate 方法的主要内容,如果未能解决你的问题,请参考以下文章

在通知上选项卡时未触发解析 onPushOpen

日期字段添加到新选项卡时未显示Datepicker

以角度切换选项卡时保持选项卡状态

使用tabview更改选项卡时如何使SwiftUI中的计时器保持触发

在Firefox中切换浏览器选项卡时jquery动画中断

用户切换浏览器选项卡时如何从 JApplet 中隐藏 JDialog?