获取结果控制器在运行时不更新表
Posted
技术标签:
【中文标题】获取结果控制器在运行时不更新表【英文标题】:Fetched Results Controller doesn't update table at runtime 【发布时间】:2017-06-27 19:59:23 【问题描述】:我尝试在 swift 3 中使用 fetched results 控制器,但它不起作用。我看到,我的实体通过我自己的 fetch 请求添加到 Core Data,但 frc 没有看到它们。如果我重新启动我的应用程序,新元素将出现在表格中。
FRC 的创建:
func getFRCForChats() -> NSFetchedResultsController<Conversation>
var fetchedResultsController: NSFetchedResultsController<Conversation>
let fetchRequest: NSFetchRequest<Conversation> = Conversation.fetchRequest()
let sortDescriptor = NSSortDescriptor(key: "conversationID", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
fetchedResultsController = NSFetchedResultsController<Conversation>(fetchRequest:
fetchRequest, managedObjectContext: container.viewContext, sectionNameKeyPath: nil, cacheName: nil)
return fetchedResultsController
使用FRC:
var fetchedResultsController: NSFetchedResultsController<Conversation>!
override func viewDidLoad()
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
coreDataService = CoreDataService()
fetchedResultsController = coreDataService.getFRCForChats()
fetchedResultsController.delegate = self
try! fetchedResultsController.performFetch()
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
if(!fetchedResultsController.sections!.isEmpty)
if let sectionInfo = fetchedResultsController.sections?[section]
return sectionInfo.numberOfObjects
else print("Unexpected Section")
return 0
func numberOfSections(in tableView: UITableView) -> Int
if let count = fetchedResultsController.sections?.count
return count
else
return 0
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "ChatCell", for: indexPath) as!ChatTableViewCell
//cell.name.text = cells[indexPath.row]
let conversation = fetchedResultsController.object(at: indexPath)
if let participants = conversation.participants as? Set<User>
conversation.managedObjectContext?.performAndWait
for user in participants
cell.name.text = user.name
break
return cell
添加新实体:
var k = 2
@IBAction func createConversation(_ sender: Any)
coreDataService.insertConversation(id: k)
k += 1
func insertConversation(id: Int)
container.performBackgroundTask (context) in
let user = User.findOrInsertUser(id: id, name: "Andrew", mobilePhone: 234567, avatar: nil, inContext: context)
_ = Conversation.findOrInsertConversation(id: id + 100, summa: Double(12+id), users: [user], transactions: [], inContext: context)
context.saveThrows()
let request: NSFetchRequest<Conversation> = Conversation.fetchRequest()
container.viewContext.perform
if let results = try? self.container.viewContext.fetch(request)
print("\(results.count) TweetMs")
for result in results
print(result.conversationID, result.summa)
代表:
extension ChatsViewController: NSFetchedResultsControllerDelegate
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>)
tableView.beginUpdates()
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>)
tableView.endUpdates()
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?)
switch type
case .delete:
if let indexPath = indexPath
tableView.deleteRows(at: [indexPath], with: .automatic)
case .insert:
if let newIndexPath = newIndexPath
tableView.insertRows(at: [newIndexPath], with: .automatic)
case .move:
if let indexPath = indexPath
tableView.deleteRows(at: [indexPath], with: .automatic)
if let newIndexPath = newIndexPath
tableView.insertRows(at: [newIndexPath], with: .automatic)
case .update:
if let indexPath = indexPath
tableView.reloadRows(at: [indexPath], with: .automatic)
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType)
switch type
case .delete:
tableView.deleteSections(IndexSet(integer: sectionIndex),
with: .automatic)
case .insert:
tableView.insertSections(IndexSet(integer: sectionIndex),
with: .automatic)
case .move, .update: break
编辑:如果我在每次编辑上下文后调用 performFetch(),表会在不调用委托的情况下重新加载。
【问题讨论】:
【参考方案1】:正如Apple Docs 所说:
automaticallyMergesChangesFromParent
一个布尔值,指示上下文是否自动合并 保存到其持久存储协调器或父上下文的更改。
尝试将其设置为true
container.viewContext.automaticallyMergesChangesFromParent = true
至少这为我解决了类似的问题。
【讨论】:
以上是关于获取结果控制器在运行时不更新表的主要内容,如果未能解决你的问题,请参考以下文章
NSLog 在 iphone 模拟器上运行时输出到控制台,但在设备上运行时不输出