【问题标题】:NSFetchedResultsController Not Auto-Updating the collection ViewNSFetchedResultsController 不自动更新集合视图
【发布时间】:2016-08-16 08:11:52
【问题描述】:

我有一个 didPressSend 函数,它接收在 textview 中写入的文本并将其作为字符串插入到上下文中。一旦插入到上下文中,NSFetchedResultsController 的 DidChangeContent 会检测到某些内容已插入到上下文中并相应地自动更新集合视图(请记住,DidChangeContent 绝对是空的)。这是我仅用于该部分的代码。 (使用文本创建消息是插入上下文的函数)。

 func didPressSendButton(button: UIButton!, withMessageText text: String!, senderId: String! ,senderDisplayName: String!, date: NSDate){

    let context = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext



   createMessageWithText(text, friend: friend!, context: moc, date: date)



    do {
        try context.save()


    } catch let err {
        print(err)
    }


}
private func createMessageWithText(text: String, friend: Friend, context: NSManagedObjectContext, date: NSDate, isSender: Bool = false) -> Mesages {
    let message = NSEntityDescription.insertNewObjectForEntityForName("Mesages", inManagedObjectContext: context) as! Mesages

    message.user = friend
    message.text = text
    message.timestamp = date
    message.isSender = isSender
    friend.lastMessage = message


    return message

}

}

一旦插入上下文,didChangeContent 就会检测到它并自动更新集合视图:

lazy var fetchedResultsControler: NSFetchedResultsController = {



    let fetchRequest = NSFetchRequest(entityName: "Mesages")
    fetchRequest.fetchBatchSize = 50
    fetchRequest.sortDescriptors = [NSSortDescriptor(key: "timestamp", ascending: true)]
    fetchRequest.predicate = NSPredicate(format: "user.id = %@", self.friend!.id!)
    let moc = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
    let frc = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: moc, sectionNameKeyPath: nil, cacheName: nil)
    frc.delegate = self
    return frc
}()



func controllerDidChangeContent(controller: NSFetchedResultsController) {

}

奇怪的是,DidChangeContent 中似乎没有任何内容似乎负责填充 collectionView,请记住,我正在使用 fetchResultsController 中的对象数量填充 collectionView:

  override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) ->

    Int {
        if let count = fetchedResultsControler.sections?[0].numberOfObjects {
            return count
        }
        return 0
}

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {


    let cell = super.collectionView(collectionView, cellForItemAtIndexPath: indexPath) as! JSQMessagesCollectionViewCell
    return cell
}

override func collectionView(collectionView: JSQMessagesCollectionView!, messageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageData! {


    let msg : Mesages = fetchedResultsControler.objectAtIndexPath(indexPath) as! Mesages
    let messageData = JSQMessage(senderId: "" , displayName: "Me", text: msg.text)
    return messageData


}

我还有一个来自 firebase 的侦听器,每当向我发送消息时,它都会立即检测到它,插入上下文中,保存,nsfetchResultsController 检测到,然后触发 didChangeContent。奇怪的是,在这种情况下它不会自动更新,除非我将collectionView.reloadData 放入didChangeContent,但是我不需要将collectionView.reloadData 放入didPressSend,因为它会神奇地自动更新。以与 didPressSend 相同的方式插入上下文的 firebase 侦听器的代码如下:(使用文本创建消息是插入上下文的函数)。

ref2.observeEventType(.ChildAdded, withBlock: {(snapshot2) in
            let messageId = snapshot2.key
            //first message ID out of 20.
            let messagesRef =     FIRDatabase.database().reference().child("messages").child(messageId)
            messagesRef.observeSingleEventOfType(.Value, withBlock: { (snapshot) in



                let dictionary = snapshot.value as! [NSObject: AnyObject]

                let timestamp = dictionary["timestamp"] as! NSNumber
                let doubleTimestamp = Double(timestamp)

                let date = NSDate(timeIntervalSinceReferenceDate: (doubleTimestamp))








                    self.createMessageWithText(dictionary["text"]! as! String, friend: friend, context: context, date: date, isSender: true)





                do {
                    try context.save()

                }

                catch {
                    print(error)

                }



   private func createMessageWithText(text: String, friend: Friend, context: NSManagedObjectContext, date: NSDate, isSender: Bool = false) -> Mesages {
    let message = NSEntityDescription.insertNewObjectForEntityForName("Mesages", inManagedObjectContext: context) as! Mesages

    message.user = friend
    message.text = text
    message.timestamp = date
    message.isSender = isSender
    friend.lastMessage = message


    return message

}

也就是说,我不确定为什么以及如何使用 NSfetchedResultsController 填充 collectionView。 (我真的担心 DidPressSend 正在填充集合视图而没有任何类型的重新加载数据)。还有一个随之而来的错误,如果我删除了 didChangeContent,你可以看到它不包含任何内容,didPressSend 会停止自动更新。当我添加空的 didChangeContent 时,集合视图开始自动更新(仅适用于 didpressSend)。

【问题讨论】:

  • 如果 fetchedResultsController 有一个委托集并且controllerDidChangeContent 存在(即使它是空的),则启用跟踪并自动更新表视图是正常的。
  • 对于 Firebase,您确定数据是插入到同一个上下文中还是同一个线程中?这可以解释为什么没有触发更新......
  • 查看 Apple 文档中的“重要”部分:developer.apple.com/library/ios/documentation/CoreData/…

标签: ios swift core-data nsfetchedresultscontroller jsqmessagesviewcontroller


【解决方案1】:

实现下面的委托方法,collectionView 或 TableView 会更新同步。尽快获得新数据。

extension ViewController: NSFetchedResultsControllerDelegate {
    func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    相关资源
    最近更新 更多