CoreData NSFetchedResultsController 简介
本文章参考 Core_Data_by_Tutorials_v2.0 翻译 代码是基于 Swift2.0
通常我们会使用一个数组来用作tableview的数据源,但这种做法的关键问题在于:假如数组特别大,而占用的内存又特别多的话,那么程序性能将受到严重的影响,这点在原来的开发中可能已经体会到了。但在早些时候,我们通过 想在CoreData 与表格视图之间高效地管理获取到的数据,最好的方式就是使用 把表格视图设置为 项目初始化下载 It all begins with a fetch request...在上边给出的链接中下载我们所要使用到的初始项目。 打开我们的ViewController.swift 文件,添加下边的代码: import CoreData ============ var fetchedResultsController: NSFetchedResultsController! 接下里在viewDidLoad中完成我们对 //1 let fetchRequest = NSFetchRequest(entityName: "Team") let sortDescriptor = NSSortDescriptor(key: "teamName",ascending: true) fetchRequest.sortDescriptors = [sortDescriptor] //2 fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest,managedObjectContext: coreDataStack.context,sectionNameKeyPath: nil,cacheName: nil) do { try fetchedResultsController.performFetch() } catch let error as NSError { print("Error: (error.localizedDescription)") }
接下里完成我们表格的数据源和单元格的配置 extension ViewController: UITableViewDataSource { func numberOfSectionsInTableView (tableView: UITableView) -> Int { return fetchedResultsController.sections!.count } func tableView(tableView: UITableView,numberOfRowsInSection section: Int) -> Int { return fetchedResultsController.sections![section].numberOfObjects } func tableView(tableView: UITableView,cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let team = fetchedResultsController.objectAtIndexPath(indexPath) as! Team let cell = tableView.dequeueReusableCellWithIdentifier( teamCellIdentifier,forIndexPath: indexPath) as! TeamCell cell.flagImageView.image = UIImage(named: team.imageName!) cell.teamLabel.text = team.teamName cell.scoreLabel.text = "Wins:(team.wins)" return cell } } run your app , your are Success !!! Modifying dataextension ViewController: UITableViewDelegate { func tableView(tableView: UITableView,didSelectRowAtIndexPath indexPath: NSIndexPath) { let team = fetchedResultsController.objectAtIndexPath(indexPath) as! Team let wins = team.wins!.integerValue team.wins = NSNumber(integer: wins + 1) coreDataStack.saveContext() tableView.reloadData() } } 当用户点击某个单元格的时候,wins数目就会改变。
Grouping results into sections接下来呢我们让 fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest,sectionNameKeyPath: "qualifyingZone",cacheName: nil)
改变每个Section的名字 func tableView(tableView: UITableView,titleForHeaderInSection section: Int) -> String? { let sectionInfo = fetchedResultsController.sections![section] return sectionInfo.name }
接下来我们改变给每个 section 里的cell 的排序。在 viewDidLoad中改变 let sortDescriptor = NSSortDescriptor(key: "teamName",ascending: true) let zoneSort = NSSortDescriptor(key: "qualifyingZone",ascending: true) let scoreSort = NSSortDescriptor(key: "wins",ascending: false) fetchRequest.sortDescriptors = [zoneSort,scoreSort,sortDescriptor] 你添加了三个
“Cache” the ball开启缓存很简单。 fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest,cacheName: "worldCup") 没错就是这么简单。
Monitoring changes`NSFetchedResultsController`可以侦听在其结果集中的变化,并通知其委托,`NSFetchedResultsControllerDelegate`。根据需要随时基础数据的变化可以使用该委托刷新表视图。 extension ViewController: NSFetchedResultsControllerDelegate { } //在viewDidLoad中 fetchedResultsController.delegate = self
Responding to changes首先呢,我们将 func controllerDidChangeContent(controller: NSFetchedResultsController) { tableView.reloadData() } 不要小看这小小的变化。现在你运行app,点击任意一个cell你回发现视图会立马改变,包括cell的位置也会发生改变。 func controllerWillChangeContent(controller: NSFetchedResultsController) { tableView.beginUpdates() } func controller(controller: NSFetchedResultsController,didChangeObject anObject: AnyObject,atIndexPath indexPath: NSIndexPath?,forChangeType type: NSFetchedResultsChangeType,newIndexPath: NSIndexPath?) { switch type { case .Delete : tableView.deleteRowsAtIndexPaths([newIndexPath!],withRowAnimation: .Automatic) case .Insert : tableView.insertRowsAtIndexPaths([indexPath!],withRowAnimation: .Automatic) case .Update : let cell = tableView.cellForRowAtIndexPath(indexPath!) as! TeamCell configureCell(cell,indexPath: indexPath!) case .Move : tableView.deleteRowsAtIndexPaths([indexPath!],withRowAnimation: .Automatic) tableView.insertRowsAtIndexPaths([newIndexPath!],withRowAnimation: .Automatic) } } func controllerDidChangeContent(controller: NSFetchedResultsController) { tableView.endUpdates() } func controller(controller: NSFetchedResultsController,didChangeSection sectionInfo: NSFetchedResultsSectionInfo,atIndex sectionIndex: Int,forChangeType type: NSFetchedResultsChangeType) { let indexSet = NSIndexSet(index: sectionIndex) switch type { case .Insert: tableView.insertSections(indexSet,withRowAnimation: .Automatic) case .Delete: tableView.deleteSections(indexSet,withRowAnimation: .Automatic) default: break } } Inserting an underdogoverride func motionEnded(motion: UIEventSubtype,withEvent event: UIEvent?) { if motion == .MotionShake { addButton.enabled = true } } @IBAction func addTeam(sender: AnyObject) { let alert = UIAlertController(title: "Secret",message: "Add a new team",preferredStyle: .Alert) alert.addTextFieldWithConfigurationHandler { (textfield) -> Void in textfield.placeholder = "Team Name" } alert.addTextFieldWithConfigurationHandler { (textfield) -> Void in textfield.placeholder = "Qualifying Zone" } alert.addAction(UIAlertAction(title: "Save",style: .Default,handler: { (actino) -> Void in let nametextfield = alert.textFields!.first let zoneTextField = alert.textFields![1] let team = NSEntityDescription.insertNewObjectForEntityForName("Team",inManagedObjectContext: self.coreDataStack.context) as! Team team.teamName = nametextfield!.text team.qualifyingZone = zoneTextField.text team.imageName = "wenderland-flag" self.coreDataStack.saveContext() })) alert.addAction(UIAlertAction(title: "Cancel",handler: { (action) -> Void in print("Cancel") })) presentViewController(alert,animated: true,completion: nil) } Where to go from here?最终项目 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |