NSFetchedResultsController更新后的新部分

时间:2017-01-06 18:23:49

标签: ios swift uitableview core-data nsfetchedresultscontroller

我有后台线程更新实体,我有tableView同时显示这个实体。 TableView在开头是空的,应该异步填充即将到来的数据。显然,第一次插入时我也增加了部分的数量。最终,我收到以下消息: CoreData:错误:严重的应用程序错误。在调用-controllerDidChangeContent:期间,从NSFetchedResultsController的委托中捕获到异常。无效更新:无效的节数。更新后的表视图中包含的节数(1)必须等于更新前的表视图中包含的节数(0),加上或减去插入或删除的节数(0插入,0删除)。使用userInfo

lazy var _result_controller: NSFetchedResultsController<Channel> =
{
    let app_delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate;

    let request: NSFetchRequest<Channel> = Channel.fetchRequest();
    request.sortDescriptors = [NSSortDescriptor(key: "frame", ascending: true), NSSortDescriptor(key: "name", ascending: true)];

    let retval: NSFetchedResultsController<Channel> = NSFetchedResultsController(fetchRequest: request,
                                                                                 managedObjectContext: app_delegate.persistentContainer.viewContext,
                                                                                 sectionNameKeyPath: "frame",
                                                                                 cacheName: nil);
    retval.delegate = self;

    self.tableView?.reloadData();

    return retval;

}();

var _block: Array<BlockOperation> = Array<BlockOperation>();

override func viewDidLoad()
{
    super.viewDidLoad()

    do {
        try _result_controller.performFetch();
    } catch let error {
        print(error);
    }
}

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?)
{
    switch(type) {
    case .insert:
        self._block.append(BlockOperation(block: {
                                                    self.tableView?.insertRows(at: [newIndexPath!], with: .bottom);
                                                    }
        ));
        // self.tableView?.scrollToRow(at: newIndexPath, at: .bottom, animated: true);
        break;
    case .update:
        self._block.append(BlockOperation(block: {
                                                    self.tableView?.reloadRows(at: [newIndexPath!], with: .bottom);
                                                    }
        ));
        break;
    default:
        break;
    }
}

func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>)
{
    self.tableView?.beginUpdates();
    for operation in self._block {
        operation.start();
    }
    self.tableView?.endUpdates();

}

override func numberOfSections(in tableView: UITableView) -> Int
{
    return self._result_controller.sections?.count ?? 0;
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
    if let count = self._result_controller.sections?[section].numberOfObjects {
        return count;
    }

    return 0;
}

我做错了什么?

UPD1 正如@pbsdf所建议的那样:

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType)
{
    switch (type) {
    case .insert:
        self.tableView?.insertSections(IndexSet(integer: sectionIndex), with: UITableViewRowAnimation.bottom);
        break;
    case .delete:
        self.tableView?.deleteSections(IndexSet(integer: sectionIndex), with: UITableViewRowAnimation.bottom);
        break;
    default:
        break;
    }
}

最后,我收到类似的错误消息: 严重的应用程序错误。在调用-controllerDidChangeContent:期间,从NSFetchedResultsController的委托中捕获到异常。无效更新:第0节中的行数无效。更新(1)后现有部分中包含的行数必须等于更新前的该部分中包含的行数(1),加上或减去数字从该部分插入或删除的行(插入1个,删除0个)并加上或减去移入或移出该部分的行数(0移入,0移出)。 userInfo(null)

0 个答案:

没有答案