NSFetchedResultsController在不推送任何插入的情况下推送更新

时间:2016-02-29 14:42:42

标签: ios swift core-data nsfetchedresultscontroller

我有一个NSFetchedResultsController初始化如下:

  lazy var postsResultsController: NSFetchedResultsController = {
    // Initialize Fetch Request
    let fetchRequest = NSFetchRequest(entityName: "Post")

    // Add Sort Descriptors
    let sortDescriptor = NSSortDescriptor(key: "creationDate", ascending: false)
    let predicate = NSPredicate(format: "owner == %@" , "owner",self.user)
    fetchRequest.sortDescriptors = [sortDescriptor]

    // Initialize Fetched Results Controller
    let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: StateControl.managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)

    // Configure Fetched Results Controller
    fetchedResultsController.delegate = self

    return fetchedResultsController
  }()

我将控制器设置为委托。以下是委托方法的概述:

  func controllerWillChangeContent(controller: NSFetchedResultsController) {
    NSLog("Begin updates")
    userPosts.beginUpdates()
  }

  func controllerDidChangeContent(controller: NSFetchedResultsController) {
    NSLog("End updates")
    userPosts.endUpdates()
  }

  func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {

    switch (type) {
    case .Insert:
      if let indexPath = newIndexPath {
        userPosts.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Left)
      }
    case .Delete:
      if let indexPath = indexPath {
        userPosts.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Left)
      }
    case .Update:
      print("Update request")
      if let indexPath = indexPath {
        userPosts.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
      }
    case .Move:
      if let indexPath = indexPath {
        userPosts.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
      }

      if let newIndexPath = newIndexPath {
        userPosts.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade)
      }
    }
  }

下面你看到我的UITableViewDataSource委托方法:

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

  func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if let sections = postsResultsController.sections {
      let sectionInfo = sections[section]
      return sectionInfo.numberOfObjects
    }
    else {return 0}
  }

  func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let post = postsResultsController.objectAtIndexPath(indexPath) as! Post
    let cell = tableView.dequeueReusableCellWithIdentifier(ReuseIdentifiers.PostCollectionViewCell, forIndexPath: indexPath) as! PostCell
    cell.setup(withPost: post, fromUser: user)
    return cell
  }

我将自己设置为tableView的didSet

中的委托
var userPosts: PostsTableView! {
    didSet {
      userPosts.delegate = self
      userPosts.dataSource = self
      userPosts.scrollEnabled = false
    }
  }

但是,当我到达viewDidLoad:时,我会执行以下操作:

do {
  try self.postsResultsController.performFetch()
} catch {
  let fetchError = error as NSError
  print("\(fetchError), \(fetchError.userInfo)")
}
userPosts.reloadData()

然而,我的tableView仍然是完全空的。我注意到的是我的日志显示userPostsController正在推送更新请求,但没有插入。

2016-02-29 15:31:52.073 Columize[10373:149421] Begin updates
Update request
2016-02-29 15:31:52.073 Columize[10373:149421] End updates
2016-02-29 15:31:52.074 Columize[10373:149421] Begin updates
Update request
2016-02-29 15:31:52.074 Columize[10373:149421] End updates

所以,我最好的猜测是NSFetchedResultsController只是监视上下文并传递更新(我从后端获取大量内容与现有对象合并,因此进行了许多更新),但我的理解是每次我创建一个新的NSFecthedResultsController,它将填充并传递相应的委托调用(主要是插入)。

此外,我认为这意味着在NSManagedObjectContextNSFecthedResultsController进行互动后,后续NSFecthedResultsController只是不推送插入内容。

1 - 我的推理是否正确? 我怎么能绕过那个?我是否必须为每个NSFecthedResultsController创建一个新的上下文?

更新

所以没有显示的原因是因为我的tableView的高度为零(wooops)。但是,如果我在第一次抓取后没有拨打reloadData,则不会显示任何内容,所以我的问题就是,为什么我的NSFetchedResultsController 没有执行任何插入操作?

0 个答案:

没有答案