切换选项卡时未调用 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语句只有在添加之后数据库的第二个项目。它没有检测到插入。 我明白了。我们需要查看更新后的代码,以及第一个控制器的代码以查看发生了什么。由于这使我们远离了当前问题(代码显示UITableView
和FRC
断开连接),我建议将您的后续问题作为一个新问题。
完成。链接是:***.com/questions/61233538/…以上是关于切换选项卡时未调用 NSFetchedResultsControllerDelegate 方法的主要内容,如果未能解决你的问题,请参考以下文章