在后台线程上执行NSFetchedResultsController的获取是一个好主意吗?

时间:2016-08-29 21:53:15

标签: ios swift multithreading core-data nsfetchedresultscontroller

当用户运行应用程序时,他首先必须登录。如果登录成功,则会触发名为setUpSaving的函数。在setUpSaving中,正如我在代码的注释部分中所写的那样(“发生了一些firebase的事情,抓住了所有的消息,并且每个消息一个接一个地,它通过createMessageWithText并将消息插入到核心数据中,最终保存它。“

所以,我的问题就在这里。假设用户有20 000条消息与他正在发送消息的人相关联。当他去ChatLogController时,所有消息必须为用户提供。我这样做的方法是使用NSFetchedResultsController执行fetch来加载登录控制器中保存的所有消息。我的问题是所有这些都在主队列上,有时候,它已经冻结了UI很长一段时间。我的chatLogController代码如下(不是全部,只是fetchedResultsController部分和collectionView),我想知道如何在后台队列上执行获取,但仍然更新主队列上的collectionView。

  func setUpSaving() {

///////some firebase stuff happens, grabs all the messages, and for each message, one by one, it goes through createMessageWithText and inserts the message into core data, 
  somewhere along the line context.save() gets triggered saving the message. 


}

private func createMessageWithText(text: String, friend: Friend, context: NSManagedObjectContext, date: NSDate, isSender: Bool = false, sentStatus: String, fromID: String) -> Mesages {

    let message = NSEntityDescription.insertNewObjectForEntityForName("Mesages", inManagedObjectContext: context) as! Mesages
    message.user = friend
    message.text = text
    message.timestamp = date
    message.isSender = isSender
    message.fromID = fromID

    message.status = sentStatus



    return message

}

}

lazy var fetchedResultsControler: NSFetchedResultsController = {
    let fetchRequest = NSFetchRequest(entityName: "Mesages")
    fetchRequest.fetchBatchSize = 20
    fetchRequest.includesPendingChanges = false
    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
}()



override func viewDidLoad() {
    super.viewDidLoad()
    NavigationItems()
    revealStatus()

    do {
        try fetchedResultsControler.performFetch()


    } catch let err {
        print(err)
    }

 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
}

1 个答案:

答案 0 :(得分:0)

不,你不应该获取将在后台线程上驱动UI的FRC。

您的问题是登录后加载20,000件商品的想法。没有人可以或将会在移动设备上查看该数量的消息。您可能希望在登录后获得20分,以及总数,但就是这样。

当用户去查看消息时,您应该根据需要加载大约20到100条消息的页面。这样,您就不会使用用户未要求您使用的资源,也不会花费任何处理时间来执行此操作。

搜索也应由服务器完成。