更重要的是,你在其他界面更新或者删除记录时,NSFetchedResultsControll
继承自 | |
遵循 | |
框架 |
/System/Library/Frameworks/
CoreData.framework
|
可用性 |
Available in iOS 3.0 and later.
|
指南 | |
定义于 |
NSFetchedResultsControll
|
相关代码 |
我们知道表格视图有很多种形式,fetched results 控制器主要针对列表视图(如图1),这种视图是由很多section组成的,每个section又包含了很多row。你只需配置:entity是什么,如何排序(必须配置),预筛选项(可选)。NSFetchedResultsControll
另外,NSFecthedResultsControll
- 监控managedobject context对象的改变,报告给delegate(可选).
- 缓冲数据,让性能有所提升,专门针对需要频繁显示的数据 (可选)。
总结一下,fetchedresults 控制器 提供下面3种模式:
1.
只提供基本的查询数据访问数据的能力。
2.
controller负责监控结果集中的数据改变,针对改变调整排序。
重要:作为这个类的delegate,至少要实现一个追踪方法:controllerDidChangeContr
使用NSFetchedResultsControll
创建控制器
一般来说,你会创建一个NSFetchedResultsControll
1。 一个fetchrequest.必须包含一个sortdescriptor用来给结果集排序。
2。 一个managedobject context。 控制器用这个context来执行取数据的请求。
3。 一个可选的keypath作为sectionname。控制器用keypath来把结果集拆分成各个section。(传nil代表只有一个section)
4。 一个cachefile的名字,用来缓冲数据,生成section和索引信息。
当你实例都创建好之后,调用performFetch:来执行查询。
NSManagedObjectContext
NSFetchRequest
//Configure the request's entity, and optionally itspredicate.
NSSortDescriptor
NSArray
[fetchRequest
[sortDescriptors
[sortDescriptor
NSFetchedResultsControll
[fetchRequest
NSError
BOOL
重要:你不可以用一个fetchedresults controller来执行几个查询,如果你非要这么做,那用deleteCacheWithName:把cachefile先删除,不然会冲突.
控制器的代理
如果你为fetchedresults控制器设置了代理,代理会收到从它的managedobject context中传来改变通知。delegate会处理context中任何会影响结果集或者section的变化,results也做相应的更新。控制器会告诉delegate结果集改变了什么或者section变化了哪些。你只要覆写几个方法来更新tableview就行。
缓存
如果有必要,控制器会使用缓存来避免重复地构造section或者把section中的内容进行排序的工作。可以说,你程序一运行,这个缓存也跟着建立好了。
当你初始化一个NSFetchedResultsControll
如果控制器找不到合适的缓存,它就计算section以及其内容的显示顺序。把结果信息写入硬盘。
如果它能找到一个同名缓存,会先检查缓存中的数据是否合法。控制器会参照当前entity的名字,entity版本信息,排序,缓存文件更改时间来判断这个缓存是否可用。
如果缓存和当前信息相兼容,控制器会复用之前存储的计算结果。
如果缓存和当前信息不兼容,控制器重新计算然后更新缓存。
一旦section和排序的信息改变了,那缓存一定会跟着改变。
所以你如果有多个fetchedresult控制器,配置得都不一样,那你最好用不用得缓存名字。
函数 deleteCacheWithName:可以直接删除一个缓存文件
实现tableview datasource方法
你可以让控制器提供相应的信息,然后实现你datasource方法。
(NSInteger)numberOfSectionsInTableV
}
-
}
-
}
-
}
-
}
-
}
响应变化
基本上,NSFetchedResultsControll
如果你允许一个用户重新对表格进行排序,那你实现的delegate方法就必须把这个也考虑进来。
其实, managed object context收到processPendingChanges消息的时候,所作的变化才有所反应。因此,如果你对一个managedobject的属性进行了更改,存储位置变化了,控制器的结果会跟着改变。但当前事件周期结束,记录的索引才跟着变化(processPendingChanges函数被调用)。比如,下面这段代码 就应该输出“same”:
NSFetchedResultsControll
NSManagedObject
NSIndexPath
[managedObject
NSIndexPath
if
}
改变查询请求
你不能只是简单地改变fetchrequest来试图改变查询结果,如果你想看到变化,你应该:
1。如果你用cache,删掉它(用deleteCacheWithName:函数)
不过一般来说,查询请求都改变了,你不太可能会用一个cache.
2。改变fetchrequest.
3。调用 performFetch:函数
对象的检查
如果一个managedobject context 告诉fetchedresult 控制器 一个单独的对象是无效的,那控制器就认为这样地对象已经被删除了,并且发送适当的delegate消息。
有的时候可能所有的对象都是无效的(比如,当我们调用reset函数或者一个存储从持久化存储管理器中被删除的时候)NSFetchResultsController
iOS 版本的问题
iOS 4.0以后,即使你重用一个cache,那管理器也不会报错,只是显示出错误的数据而已(这样可以削减程序启动时复杂的字符串比较,提高效率)。所以注意不要重复使用!
子类需要注意
如果你想自定义section的创建,索引的标题,那你可能会子类这个控制器。你可以覆写sectionIndexTitleForSect
如果你想section的名字不是大写字母开头,而是其他的,你可以覆写sectionIndexTitles。
如果你想索引的名字是其他的内容,为每个已知section覆写sectionIndexTitleForSect