保存到核心数据时NSFetchedResultsController不更新

时间:2015-09-17 02:09:22

标签: swift uitableview core-data nsfetchedresultscontroller

以下任何想法?非常感谢:

我已设置NSFetchedResultsController,如下所示:

var _fetchedResultsController: NSFetchedResultsController?

var fetchedResultsController: NSFetchedResultsController {

    if self._fetchedResultsController != nil {
        return self._fetchedResultsController!
    }
    let entity = NSEntityDescription.entityForName("Messages", inManagedObjectContext: self.mOC)

    let messageRequest = NSFetchRequest()
    messageRequest.entity = entity
    let messagePredicate = NSPredicate(format: "messageFrom = %@ OR messageTo = %@", profileID, profileID)
    messageRequest.predicate = messagePredicate
    messageRequest.fetchBatchSize = 20
    let sectionSortDescriptor = NSSortDescriptor(key: "messageDate", ascending: true)
    let sortDescriptors = [sectionSortDescriptor]
    messageRequest.sortDescriptors = sortDescriptors

    let frc = NSFetchedResultsController(fetchRequest: messageRequest, managedObjectContext: self.mOC, sectionNameKeyPath: "sectionTitle", cacheName: nil)
    frc.delegate = self
    self._fetchedResultsController = frc
    return self._fetchedResultsController!

}

它通过与聊天实体的多对多关系链接。聊天>>消息。一个聊天者(由CurrentChatter定义)有很多消息。

当我加载tableview时...消息在ViewDidLoad()

中使用以下内容完美显示
do {
    try fetchedResultsController.performFetch()
} catch let fetchError as NSError {
    print("I have been unable to fetch things .. : \(fetchError)")
}

当我使用以下样板代码保存消息时,NSFetchedResultsController似乎没有发生任何事情。 tableView由于某种原因没有更新,我似乎无法解决原因。我已经NSFetchedResultsControllerDelegate到位并定义了。

if let newMessage = NSEntityDescription.insertNewObjectForEntityForName("Messages", inManagedObjectContext: mOC) as? Messages {
    newMessage.messageDate = NSDate()
    newMessage.messageFrom = myMainUser.mainUserIDfromServer
    newMessage.messageMustBeSent = false
    newMessage.messageReceivedAtServer = true
    newMessage.messageCode = 0
    newMessage.messageType = 100
    newMessage.messageText = "Here is a message I am sending to you!"
    newMessage.messageTo = Int(profileID)!
    newMessage.messageNewMessage = false

    currentChatter.mutableSetValueForKey("messages").addObject(newMessage)          

    do {
        try mOC.save()
    } catch let saveError as NSError {
        print("I have not been able to save the message ...: \(saveError)")
    }
}

我正在调用mOC.save。我已经检查过它已保存并且保存到同一个ManagedObjectContext。\ n \ n当我手动刷新tableview时,会显示新消息。

为了测试这是否有效我有一个简单的print语句如下:

func controllerWillChangeContent(controller: NSFetchedResultsController) {

    print("I will make changes?")

}

毋庸置疑,这不会被召唤。

这是因为新消息是作为CurrentChatter的一部分添加的。或者每次消息实体发生变化时都应该更新?还是我完全错过了什么? 3个小时就可以了,我也没有理解为什么它不起作用了。

提前致谢。

更新

我已添加代码按日期对表格进行排序(已添加以供参考):

import Foundation
import CoreData

class Messages: NSManagedObject {

    func sectionTitle() -> String {

        let myDate = NSDateFormatter()
        myDate.dateFormat = "d MMM YYYY"
        return myDate.stringFromDate(self.messageDate)
    }

}

3 个答案:

答案 0 :(得分:2)

您设置了委托,但是您是否实施了controller didChangeObject等?你需要这样的东西:

    func controllerWillChangeContent(controller: NSFetchedResultsController) {
        tableView.beginUpdates()
    }

    func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
        switch type {
        case .Insert:
            tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: UITableViewRowAnimation.Automatic)
        case .Delete:
            tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: UITableViewRowAnimation.Automatic)
        case .Update
            // update cell at indexPath
        case .Move:
            tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: UITableViewRowAnimation.Automatic)
            tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: UITableViewRowAnimation.Automatic)
        }
    }

    func controllerDidChangeContent(controller: NSFetchedResultsController) {
        tableView.endUpdates()
    }

答案 1 :(得分:2)

我有类似的问题。在我的例子中,问题是我在使用NSFetchedResultsController()调用的结果实例化之前在类型变量上设置了NSFRC委托。因此没有设置委托,也没有任何委托方法可行。

愚蠢的错误,我知道,但是花了一段时间才找到它。

在您的情况下,如果您在type中找到了didChangeObject的内容,那么您的代表工作正常。

你说你得到type的错误值。打印type枚举的原始值以查看它们是什么。以下是Apple关于他们的文档的链接:

https://developer.apple.com/library/prerelease/ios/documentation/CoreData/Reference/NSFetchedResultsControllerDelegate_Protocol/index.html#//apple_ref/c/tdef/NSFetchedResultsChangeType

他们在switch声明中的顺序应该无关紧要,只要它是广泛的(包括所有)。

此外,请确保您不期望一种类型并接收另一种类型。例如:

如果添加新条目,您会期望.Insert正确吗?但是如果您在NSFRC描述符中按name排序,则会收到.Move,因为新添加可能会导致行重新排列。

这也发生在我身上并花了一些时间才找到。

希望这有点帮助。

答案 2 :(得分:0)

如果将更新语句放在didChangeObject中的.Insert之前(所以把它放在第一位),这有帮助吗?我有相同的行为,这为我解决..至少,在我的设备上。我现在听到beta测试人员遇到同样的问题.. :(