《Core Data应用开发实践指南》一2.13 获取托管对象

2.13 获取托管对象

想操作托管对象上下文中的现有数据,就必须先把它获取(fetch)过来。假如待获取的数据没有放在上下文里,那么Core Data会从底层的持久化存储区里把它拿出来,这个过程对开发者来说是透明的。要执行获取操作,就得有NSFetchRequest实例,该实例会返回NSArray,这个数组里面的元素都是托管对象。在执行获取操作的时候,NSFetchRequest会根据特定的实体,把每个托管对象都放在NSArray这个数组中,并将其返回给调用者。用SQL数据库领域的术语来说,获取操作类似于SELECT语句。相关代码如程序清单2-4所示。

请按照下列步骤修改Grocery Dude,以便获取Item实体的所有实例:
把程序清单2-4中的代码添加到AppDelegate.m文件的demo方法里面。
运行程序并注意控制台中输出的日志,你将会看到12行非常相似的信息,每一行信息都代表从数据库中取出的一个托管对象。假如你的数据库里有重复数据,那么具体的行数可能和书中列出的有所不同。图2-10演示了正常运行程序时所产生的结果。

如果想查看每个托管对象的特性值,那么可以用for循环来遍历NSArray,并用NSLog把每个item的name特性值打印出来。相关代码如程序清单2-5所示。

请按下列步骤修改Grocery Dude,以便在控制台的日志中显示出每个item的name:
1. 把AppDelegate.m文件的demo方法改为程序清单2-5的样子。方法开头的NSLog语句可以保留,也可以删掉。
重新运行应用程序,并观察控制台中的日志,现在应该可以看到每个托管对象的name特性值了。正常的运行效果如图2-11所示。

2.13.1 对获取请求的结果进行排序

NSFetchRequest执行完毕之后,会返回NSArray,而NSArray本身就支持对其中的元素进行排序。另外,我们也可以换一种办法,就是给NSFetchRequest配置排序描述符(sort descriptor),这样的话,NSFetchRequest就可以直接按特定方式对获取到的托管对象进行排序了。这个排序描述符是作为NSSortDescriptor的实例传给NSFetchRequest的。用SQL数据库的术语来说,排序描述符就类似于ORDER BY语句。程序清单2-6列出了相关代码。

请按下列步骤修改Grocery Dude,以便对获取到的托管对象进行排序:
1. 修改AppDelegate.m文件的demo方法,用程序清单2-6中的粗体代码把原有的相关代码替换掉。
再次运行应用程序,并查看控制台中的日志,你会发现托管对象已经按照其名称的字母顺序排列好了。正常的运行效果如图2-12所示。

2.13.2 对获取请求的结果进行筛选

有时我们并不想把与某个实体有关的全部对象都获取过来,这时可以通过谓词来筛选。我们采用NSPredicate实例来定义谓词,并将其传给NSFetchRequest实例。有了谓词之后,获取请求就会根据谓词中的标准来限定获取到的托管对象的数量。由于谓词与具体的持久化存储区无关,所以不论后端采用何种存储区,都可以使用相同的谓词来筛选它。但是,在特殊情况下,某些谓词无法适用于特定格式的存储区。比方说,matches操作符可以对in-memory存储区执行筛选,却不能用在SQLite格式的存储区上。以SQL数据库的术语来说,谓词类似于WHERE子句。
在获取请求的执行过程中,系统要根据每个托管对象来对谓词分别求值。谓词的求值结果是个Boolean值。如果是YES,那就表明该托管对象符合谓词中的标准,于是也就可以留在最终的获取结果中;但若是NO,则表示该对象不符合谓词中的标准,于是就会从最终的获取结果中剔除。
执行完NSFetchRequest之后,获取到的结果会存放在NSArray里面,此时就可以按照自己的需要对这个数组里面的托管对象进行筛选了。可以用NSArray的filteredArrayUsingPredicate方法来筛选,也可以用NSMutableArray的filter-UsingPredicate方法执行就地筛选。
以Grocery Dude程序为例,假设我们现在要把名称为Coffee的货品排除掉。在创建传递给NSFetchrequest的NSPredicate时,我们可以指明name不等于字符串Coffee。这个谓词写成代码就是name!=@"Coffee"。由于谓词支持变量替换,所以我们可以像程序清单2-7中的粗体代码那样,等到运行期再向谓词传入字符串。构建谓词所需的逻辑有时比较简单,有时却相当复杂,这要根据需求来定。有关谓词的更多信息,请访问http://developer.apple.com/网站并搜索Predicate Programming Guide。

请按下列步骤修改Grocery Dude,向其中添加谓词,以便筛选获取到的托管对象:
1. 修改AppDelegate.m文件的demo方法,用程序清单2-7中的粗体代码把原有的相关代码替换掉。
运行应用程序,并观察控制台中的日志,你应该会发现:在列出的货品名称中,已经没有Coffee这一项了。正常的运行结果如图2-13所示。

2.13.3 获取请求模板

假如每次获取托管对象时都要手工编写谓词格式确实很累人,幸好Xcode的Data Model Designer有预定义获取请求的功能。这些可复用的模板比谓词更容易配置,而且还能减少重复代码。只需根据应用程序的模型来操作一系列下拉列表框及文本框,即可配置好一份获取请求模板。但如果要自定义AND、OR这样的逻辑组合,那么这个模板就无法满足要求了,此时仍然需要通过代码来指定谓词。
请按下列步骤修改Grocery Dude,以创建获取请求模板:
1. 选中Model.xcdatamodeld。
2. 点击Editor>Add Fetch Request菜单项。
3. 把获取请求模板的名称设为Test。
4. 点击“+”按钮来配置名为Test的获取请求模板,如图2-14所示。

要想使用获取请求模板,需要先给托管对象模型发送消息,告诉它将要使用的模板叫什么名字。发送完消息之后,就可以在返回的NSFetchRequest上面操作了。由于这种获取请求是根据模板创建出来的,所以开发者无需通过向其发送谓词来执行筛选操作。假如想修改这种获取请求(比方说,要对其进行排序),那么必须先制作它的一份拷贝,这是因为获取请求模板是根据不可变的模型(immutable model或unchangeable model)创建出来的。相关代码如程序清单2-8所示。

请按下列步骤修改Grocery Dude,以便使用名为Test的获取请求模板:
1. 修改AppDelegate.m文件中的demo方法,用程序清单2-8中的代码替换原有的代码。程序清单2-8中的那行粗体代码是新加进来的,另外,修改过的代码中是没有谓词的。
运行应用程序,并观察控制台中的日志,你会发现这些托管对象均已按照名称排过序,而且只有名称中包含字母e的对象才会出现在控制台中,这些效果都是通过配置获取请求模板而实现出来的。正常的运行结果如图2-15所示。

不知你是否注意到了系统为这次fetch操作所生成的SQL语句。这条SQL语句的意思就是对获取到的各个Item进行筛选与排序(“获取”对应于语句中的“SELECT”;“筛选”对应于语句中的“WHERE”;“排序”对应于语句中的“ORDER BY”)。正常的运行效果如图2-16所示。

时间: 2024-09-25 18:03:11

《Core Data应用开发实践指南》一2.13 获取托管对象的相关文章

《Core Data应用开发实践指南》一3.5 通过迁移管理器来迁移数据

3.5 通过迁移管理器来迁移数据 除了通过NSPersistentStoreCoordinator来迁移存储区之外,还可以采用迁移管理器来做.迁移管理器可以使开发者全权掌控迁移过程中创建的文件,从而令他们能够按自己的方式来灵活处理迁移中的各种问题.使用迁移管理器的一个好处就是可以向用户报告迁移进度,使用户知道应用程序哪次会启动得比较慢一些,所以需要耐心等待.虽说迁移过程理应执行得非常快才对,但当数据库比较大.变动比较复杂时,迁移过程就需要耗费一定的时间了.为了使用户界面保持流畅,迁移过程必须在后

《Core Data应用开发实践指南》一1.2 Core Data的适用场合

1.2 Core Data的适用场合 如果应用程序要保存的设置数据太多,以致NSUserDefaults及"特性列表"(property list)这种简单的存储方案无法应付,那么就会出现内存占用量方面的问题.解决办法是直接使用数据库或通过Core Data来间接操作数据库.选用Core Data的好处是,不用再花时间编写数据库接口的代码了.此外,你还将享受性能方面的优势,而且可以使用诸如撤销及验证等强大的功能.假如选择直接使用数据库,那就要花时间去做开发与测试工作,也就是通常所说的&

《Core Data应用开发实践指南》一3.1 修改托管对象模型

3.1 修改托管对象模型 在应用程序的进化过程中,其托管对象模型也可能需要改变.对于一些比较简单的修改,诸如设定属性的默认值.设定验证规则.使用获取请求模板等,是可以直接实施的.而对于另外一些更为结构化的(structural)修改,则需先把持久化存储区迁移到新的模型版本才行.假如没有提供迁移数据所需的映射与设定,那么应用程序就会崩溃.为了继续构建范例程序,需要把上一章中的代码添加到Grocery Dude项目中.或者可以去http://www.timroadley.com/LearningCo

《Core Data应用开发实践指南》一2.2 添加托管对象模型

2.2 添加托管对象模型 在第1章中,我们通过CoreDataHelper.m文件里的mergedModelFromBundles方法初始化了托管对象模型.然而现在的问题是:项目里根本就没有模型可用!如果连模型都没有的话,那Core Data就彻底失去意义了,所以,我们这个时候应该创建模型文件.模型文件一般会含有"对象图",而对象图则用来表示应用程序的数据结构以及其他一些可以简化应用程序开发的东西,我们稍后再来解释.请按下列步骤修改Grocery Dude,以便添加数据模型文件: 在现

《Core Data应用开发实践指南》一第1章 初次尝试Core Data应用程序

第1章 初次尝试Core Data应用程序 如果不能把一件事用简单的话说清楚,那就表明你理解得还不够透彻.-阿尔伯特•爱因斯坦"体验式学习"(kinesthetic learning)或者说"从实践中学习"(learning by doing),是接收并记住信息的绝佳手段.即便对于许多有经验的程序员来说,Core Data也是个相当棘手的话题,于是,笔者就适时地编写了你手中的这本书,它以实践的方式来讲解Core Data.本书不会过早地讲解一些比较难懂的话题,本章只

《Core Data应用开发实践指南》一1.3 创建Grocery Dude项目

1.3 创建Grocery Dude项目 Grocery Dude是个运行在iPhone上的范例程序,在学习本书的过程中,你将了解到它的制作流程.学会了Core Data中的某个特性或某项开发技巧之后,你可以将其运用在Grocery Dude程序上面.到了本书收尾的时候,你将会制作好一款功能完备而且运行速度很快的Code Data程序,它能够同iCloud紧密地集成在一起.假如你现在就想直接看看成品,那可以去App Store下载Grocery Dude.请注意,Grocery Dude是专门为

《Core Data应用开发实践指南》一3.3 轻量级的迁移方式

3.3 轻量级的迁移方式 把新模型设为当前版本之后,必须迁移现有的持久化存储区,只有这样,才能正常使用新模型.这是因为,持久化存储区协调器会试着用新版的模型来打开原有的存储区,但由于原有的存储区是用旧版模型创建的,所以该操作会失败.在向NSPersis-tentStoreCoordinator添加存储区的时候,只需将下列选项放在NSDictionary里传过去,即可自动完成存储区的迁移工作:如果传给NSPersistentStoreCoordinator的NSMigratePersistentS

《Core Data应用开发实践指南》一1.4 为现有的应用程序添加Core Data支持

1.4 为现有的应用程序添加Core Data支持 在Xcode中创建iOS应用程序项目时,可以使用各种起始模板(starting-point template).假如要根据Master-Detail.Utility Application或Empty Application等模板来创建项目,那么只需勾选Use Core Data,即可在项目中使用Core Data.不过,Grocery Dude项目是根据Single View Application模板创建的,它起初并没有包含Core Dat

《Core Data应用开发实践指南》一2.12 后端SQL的可见性

2.12 后端SQL的可见性 如果只在控制台的日志中查看Core Data所输出的结果,那么意义并不算太大.你知不知道这些事情背后究竟发生了什么?Core Data对持久化存储区中的数据到底进行了哪些操作?这些操作是否恰当?为了提供无缝的Core Data体验,系统都生成了哪些SQL查询语句?每次在模拟器中运行程序的时候,是不是会插入重复的对象? 有个极其详尽的调试选项可以提供足够的信息,告诉你这些操作背后所发生的事情,从而令你知道上述那些问题的答案.这个调试选项会把系统自动生成的SQL查询语句