在前四节的实例中,我们都使用了table view作为core data的数据显示容器,这是因为core data能够很好的和table view进行配合。创建fetch request,获取一组managed object,将结果作为table view的数据源。UITableView和Core Data是通过NSFetchedResultsController联系在一起的。正确的使用NSFetchedResultsController将使得只用写少量的代码就让table使用core data做数据源。在这一节中,我们将会学习如何使用这个类以及什么时候应该使用它。
转载请注明出处:http://blog.csdn.net/yamingwu/article/details/42400707
源代码地址:https://github.com/dnawym/StudySwift/tree/master/CoreData/WorldCup
World Cup app:
这一节的示例程序是一个用于显示世界杯积分榜的应用程序。这个程序会将参加世界杯的所有队伍现在主页上。点击任意国家的cell将增加这个国家的获胜次数。拥有最高获胜次数的过奖将赢得世界杯。这个计分规则十分简单,但是足够演示如何使用NSFetchedResultsController了。
这个程序由一个有20个cell的table view构成,每个cell代表一个国家,蓝色处为国旗位置。
从Fetch Request开始:
修改ViewController.swift,引入CoreData并添加成员变量
import CoreData
var fetchedResultsController: NSFetchedResultsController!在viewDidLoad中添加以下代码:
override func viewDidLoad() {
super.viewDidLoad()
// 创建fetch request
let fetchRequest = NSFetchRequest(entityName: "Team")
// 创建Controller,提供执行上下文-managedObjectContext
fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: coreDataStack.context, sectionNameKeyPath: nil, cacheName: nil)
// 执行fetch request
var error: NSError? = nil
if (!fetchedResultsController.performFetch(&error)) {
println("Error: \(error?.localizedDescription)")
}
}performFetch的返回值是一个Bool变量,true代表成功,false代表失败。而执行的结果存放在controller的fetchedObjects属性中,通过objectAtIndexPath方法,可以访问到fetch的结果。
添加以下代码:
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return fetchedResultsController.sections!.count
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let sectionInfo = fetchedResultsController.sections![section] as NSFetchedResultsSectionInfo
return sectionInfo.numberOfObjects
} 由于NSFetchedResultsController不能只使用简单的fetch request,需要为其提供SortDescriptor,否则,程序会crush,添加以下代码到初始化fetch request位置:
let sortDescriptor = NSSortDescriptor(key: "teamName", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]程序执行效果如下:
通过点击cell修改数据:
由于Core Data将整数存储为NSNumber,这里需要unwarp wins在修改它,再转换为NSNumber
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
let team = fetchedResultsController.objectAtIndexPath(indexPath) as Team
let wins = team.wins.integerValue
team.wins = NSNumber(integer: wins + 1)
coreDataStack.saveContext()
tableView.reloadData()
} 程序执行结果如下:
分区:
世界杯有六个区,我们也按这六个区对国家进行section划分
修改viewDidLoad,增加sectionNameKeyPath
fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: coreDataStack.context, sectionNameKeyPath: "<span style="color:#ff0000;">qualifyingZone</span>", cacheName: nil)显示section名
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
let sectionInfo = fetchedResultsController.sections![section] as NSFetchedResultsSectionInfo
return sectionInfo.name
}修改sort descriptor,让结果首先按zone排序,相同的zone按输赢多少排序,胜场相同按字母序排序。
let zoneSort =
NSSortDescriptor(key: "qualifyingZone", ascending: true)
let scoreSort =
NSSortDescriptor(key: "wins", ascending: false)
let nameSort =
NSSortDescriptor(key: "teamName", ascending: true)
fetchRequest.sortDescriptors = [zoneSort, scoreSort, nameSort]这里需要将qualifyingZone作为第一个key,因为我们想使用section作为分隔。
Cache数据:
对数据进行遍历和排序需要花费大量的时间,尤其是在数据量很大的时候,此时,我们可以使用NSFetchResultsController的缓存机制来解决这个问题
fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: coreDataStack.context, sectionNameKeyPath: "qualifyingZone", cacheName: "<span style="color:#ff0000;">worldCup</span>")
本文介绍如何使用NSFetchedResultsController简化UITableView与CoreData的结合,包括FetchRequest创建、数据排序、分区展示及缓存机制。
NSFetchedResultsController 上&spm=1001.2101.3001.5002&articleId=42400707&d=1&t=3&u=f8f53ab53cbc41188ee17e73b02945b3)
1598

被折叠的 条评论
为什么被折叠?



