小编典典

NSFetchedResultsController仅在控制器将要插入另一节时才将同一单元格插入两节中

swift

这是我的Message.swift文件:

@objc(Message)
class Message: NSManagedObject {

    @NSManaged var content: String
    @NSManaged var createdAt: NSDate
    @NSManaged var identifier: Int64

    @NSManaged var conversation: Conversation

    @NSManaged var sender: Contributor

    var normalizedCreatedAt: NSDate {
        return createdAt.dateWithDayMonthAndYearComponents()!
    }
}

这是我设置FRC的方式:

private func setupFetchedResultsController() {

    let context = NSManagedObjectContext.MR_defaultContext()
    let fetchRequest = NSFetchRequest(entityName: "Message")
    let createdAtDescriptor = NSSortDescriptor(key: "createdAt", ascending: true)

    fetchRequest.predicate = NSPredicate(format: "conversation.identifier = %lld", conversation.identifier)
    fetchRequest.sortDescriptors = [createdAtDescriptor]

    fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: "normalizedCreatedAt", cacheName: nil)
    fetchedResultsController.delegate = self

    try! fetchedResultsController.performFetch()
    tableView.reloadData()
}

与它的标准代表。

viewDidLoad我的控制器上有1节和1行。我使用以下功能在控制台上打印它:

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

    print("--->>>")
    print(section)
    print(fetchedResultsController.sections![section].objects!.count)
    return fetchedResultsController.sections![section].objects!.count
}

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return fetchedResultsController?.sections?.count ?? 0
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let message = fetchedResultsController?.objectAtIndexPath(indexPath) as! Message
    let cellIdentifier = message.sender.identifier == Settings.currentUser?.profile?.identifier ? SentTableViewCellIdentifier : ReceivedTableViewCellIdentifier
    let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! TableViewCell

    cell.cellTitleLabel?.text = message.content

    return cell
}

输出如下:

--->>>
0
1

一旦我尝试只添加一条带有不同部分的其他消息,就会得到以下消息:

--->>>
0
2
--->>>
1
1

然后是错误:

CoreData:错误:严重的应用程序错误。在调用-
controllerDidChangeContent:期间,从NSFetchedResultsController的委托捕获了一个异常。无效的更新:第0节中的行数无效。更新(2)之后,现有节中包含的行数必须等于更新(1)之前该节中包含的行数。从该部分插入或删除的行数(已插入0,已删除0),加上或减去移入或移出该部分的行数(移入0,移出0)。与userInfo(空)

为什么会这样呢?

NSFetchedResultsController由于某种原因,将同一个单元格装入两个部分: firstsecond 。为什么?

注意:

  • 仅在FRC插入新节时才会出现此问题。如果需要在现有部分中插入行,则没有问题。问题与章节有关。
  • 仅当FRC尝试插入第二个部分时,问题才出现。当大约是第三或第四部分时,根本没有问题。

阅读 238

收藏
2020-07-07

共1个答案

小编典典

我不知道为什么,但是要使其正常工作,您需要更换:

fetchedResultsController.sections![section].objects!.count

fetchedResultsController.sections![section].numberOfObjects

由于某种原因,objects!.count返回与属性相反的对象数量 不正确numberOfObjects

2020-07-07