我在viewDidLoad中获取了一些项目(NSManagedObject),并且我正在使用NSFetchedResultsController委托来更新swift ios中的tableView单元(来自Apple文档的代表进行插入,删除等操作),问题是当我添加一个项目时对于相同ManagedObject类型的核心数据,我希望该表使用新项进行更新,但是最后一项从表视图中删除,并且不添加新项。当我再次加载屏幕时,我只会看到新项目……可能是什么问题?
这是我的fetchedResultsController:

lazy var fetchedResultsController: NSFetchedResultsController<Message> = {
    let context = CoreDataManager.shared.persistentContainer.viewContext
    let request: NSFetchRequest<Message> = Message.fetchRequest()

    request.sortDescriptors = [
        NSSortDescriptor(key: "createdAt", ascending: true)
    ]
    request.fetchLimit = 40

    let frc = NSFetchedResultsController(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)

    // fetch only messages with that recipient id of the chat.
    let recipientId = "\(chat!.recipientId)"
    request.predicate = NSPredicate(format: "recipientId == %@", recipientId)

    return frc
}()


这就是我创建和添加新消息的方式

func createNewTextMessage(recipientId: String, content: String) {

    ...

    guard let id = Int32(recipientId) else { return }
    guard let chat = fetchSingleChat(recipientId: id) else { return }

    let context = persistentContainer.viewContext
    let message = Message(context: context)

    let date = Date()

    message.chatId = chat.id
    message.createdAt = date
    message.isRead = false
    message.senderId = Int32(currentUserId)
    message.senderName = currentUserName
    message.senderPhoneNumber = currentUserPhoneNumber
    message.status = MessageStatus.unsent.rawValue
    message.type = MessageType.text.rawValue
    message.owner = MessageOwnerType.mine.rawValue
    message.content = content
    message.recipientId = chat.recipientId
    message.recipientName = chat.title

    message.messageId = "\(currentUserToken)_\(date.millisecondsSince1970)"

    // here's where i'm setting some relationship (chat to message: 1-to-many)
    message.chat = chat
    chat.lastMessage = message
    message.chat?.lastMessage = message

    do {
        try context.save()
    } catch let err {
        print("failed to save private chat:", err)
    }

}


聊天ManagedObject具有lastMessage的属性,该属性的类型为Message(也是托管对象),我将新创建的消息设置为Chat的最后一条消息。问题出在那儿吗?
这也是委托代码:

// MARK: - NSFetchedResultsController Delegates

func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
    tableView.beginUpdates()
}

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {
    switch type {
    case .insert:
        tableView.insertSections(IndexSet(integer: sectionIndex), with: .fade)
    case .delete:
        tableView.deleteSections(IndexSet(integer: sectionIndex), with: .fade)
    case .move:
        break
    case .update:
        break
    }
}

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
    switch type {
    case .insert:
        tableView.insertRows(at: [newIndexPath!], with: .right)
    case .delete:
        tableView.deleteRows(at: [indexPath!], with: .fade)
    case .update:
        tableView.reloadRows(at: [indexPath!], with: .fade)
    case .move:
        tableView.moveRow(at: indexPath!, to: newIndexPath!)
    }
}

func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
    tableView.endUpdates()
}

最佳答案

请注意,您对移动行(.move)的处理只会移动一行,您应该实施它才能移动许多行。不确定这是否可以解决您的问题,这取决于数据的排序方式。

这是我实现.move的方式

case .move:
    if let indexPath = indexPath {
        tableView.removeRows(at: IndexSet(integer: indexPath.item), withAnimation: .effectFade)
    }
    if let newIndexPath = newIndexPath {
        tableView.insertRows(at: IndexSet.init(integer: newIndexPath.item), withAnimation: .effectFade)
    }

09-25 19:23