认识CoreData-使用进阶
来源:互联网 发布:js时间段选择控件 编辑:程序博客网 时间:2024/06/06 02:49
该文章属于<简书 — 刘小壮>原创,转载请注明:
<简书 — 刘小壮> http://www.jianshu.com/p/a4710356244d
之前两篇文章都比较偏理论,文字表达比较多一些,但都是干货!学习时先理解理论知识,才能更好的帮助后面的理解。
在这篇文章中,将会涉及关于CoreData的一些复杂操作,这些操作会涉及分页查询、模糊查询、批处理等高级操作。 通过这些操作可以更好的使用CoreData,提升CoreData性能。文章中将会出现大量示例代码,通过代码的方式更有助于理解。 文章内容还会比较多,希望各位耐心看完。
文章中如有疏漏或错误,还请各位及时提出,谢谢!
NSPredicate
概述
在
iOS
开发过程中,很多需求都需要用到过滤条件。例如过滤一个集合对象中存储的对象,可以通过Foundation
框架下的NSPredicate
类来执行这个操作。
CoreData
中可以通过设置NSFetchRequest
类的predicate
属性,来设置一个NSPredicate
类型的谓词对象当做过滤条件。通过设置这个过滤条件,可以只获取符合过滤条件的托管对象,不会将所有托管对象都加载到内存中。这样是非常节省内存和加快查找速度的,设计一个好的NSPredicate
可以优化CoreData
搜索性能。语法
NSPredicate
更加偏向于自然语言,不像SQLite
一样有很多固定的语法,看起来也更加清晰易懂。例如下面需要查找条件为年龄30岁以上,并且包括30岁的条件。
[NSPredicate predicateWithFormat:@"age >= 30"]
过滤集合对象
可以通过
NSPredicate
对iOS
中的集合对象执行过滤操作,可以是NSArray
、NSSet
及其子类。对不可变数组
NSArray
执行的过滤,过滤后会返回一个NSArray
类型的结果数组,其中存储着符合过滤条件的对象。
NSArray *results = [array filteredArrayUsingPredicate:predicate]
对可变数组
NSMutableArray
执行的过滤条件,过滤后会直接改变原集合对象内部存储的对象,删除不符合条件的对象。[arrayM filterUsingPredicate:predicate]
复合过滤条件
谓词不只可以过滤简单条件,还可以过滤复杂条件,设置复合过滤条件。
[NSPredicate predicateWithFormat:@"(age < 25) AND (firstName = XiaoZhuang)"]
当然也可以通过
NSCompoundPredicate
对象来设置复合过滤条件,返回结果是一个NSPredicate
的子类NSCompoundPredicate
对象。[[NSCompoundPredicate alloc] initWithType:NSAndPredicateType subpredicates:@[predicate1, predicate2]]
枚举值
NSCompoundPredicateType
参数,可以设置三种复合条件,枚举值非常直观很容易看懂。
- NSNotPredicateType
- NSAndPredicateType
- NSOrPredicateType
基础语法
下面是列举的一些
NSPredicate
的基础语法,这些语法看起来非常容易理解,更复杂的用法可以去看苹果的官方API。语法 作用 ==判断是否相等>=大于或等于<=小于或等于>大于<小于!=不等于AND 或 &&和OR 或 II或NOT 或 !非正则表达式
NSPredicate
中还可以使用正则表达式,可以通过正则表达式完成一些复杂需求,这使得谓词的功能更加强大,例如下面是一个手机号验证的正则表达式。
NSString *mobile = @"^1(3[0-9]|5[0-35-9]|8[025-9])\\d{8}$";NSPredicate *regexmobile = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", mobile];
模糊查询
NSPredicate
支持对数据的模糊查询,例如下面使用通配符来匹配包含lxz的结果,具体CoreData
中的使用在下面会讲到。
[NSPredicate predicateWithFormat:@"name LIKE %@", @"*lxz*"]
keyPath
NSPredicate
在创建查询条件时,还支持设置被匹配目标的keyPath
,也就是设置更深层被匹配的目标。例如下面设置employee
的name
属性为查找条件,就是用点语法设置的keyPath
。
[NSPredicate predicateWithFormat:@"employee.name = %@", @"lxz"]
设置查询条件
在之前的文章中,执行下面
MOC
的fetchRequest
方法,一般都需要传入一个NSFetchRequest
类型的参数。这个request
参数可以做一些设置操作,这样就可以以较优的性能获取指定的数据。
- (nullable NSArray *)executeFetchRequest:(NSFetchRequest *)request error:(NSError **)error;
NSFetchRequest
在执行
fetch
操作前,可以给NSFetchRequest
设置一些参数,这些参数包括谓词、排序等条件,下面是一些基础的设置。
- 设置查找哪个实体,从数据库的角度来看就是查找哪张表,通过
fetchRequestWithEntityName:
或初始化方法来指定表名。- 通过
NSPredicate
类型的属性,可以设置查找条件,这个属性在开发中用得最多。NSPredicate
可以包括固定格式的条件以及正则表达式。- 通过
sortDescriptors
属性,可以设置获取结果数组的排序方式,这个属性是一个数组类型,也就是可以设置多种排序条件。(但是注意条件不要冲突)- 通过
fetchOffset
属性设置从查询结果的第几个开始获取,通过fetchLimit
属性设置每次获取多少个。主要用于分页查询,后面会讲。
MOC
执行fetch
操作后,获取的结果是以数组的形式存储的,数组中存储的就是托管对象。NSFetchRequest
提供了参数resultType
,参数类型是一个枚举类型。通过这个参数,可以设置执行fetch
操作后返回的数据类型。
- NSManagedObjectResultType: 返回值是
NSManagedObject
的子类,也就是托管对象,这是默认选项- NSManagedObjectIDResultType: 返回
NSManagedObjectID
类型的对象,也就是NSManagedObject
的ID
,对内存占用比较小。MOC
可以通过NSManagedObjectID
对象获取对应的托管对象,并且可以通过缓存NSManagedObjectID
参数来节省内存消耗- NSDictionaryResultType: 返回字典类型对象
- NSCountResultType: 返回请求结果的
count
值,这个操作是发生在数据库层级的,并不需要将数据加载到内存中设置获取条件
// 建立获取数据的请求对象,并指明操作Employee表NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Employee"];// 设置请求条件,通过设置的条件,来过滤出需要的数据NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name = %@", @"lxz"];request.predicate = predicate;// 设置请求结果排序方式,可以设置一个或一组排序方式,最后将所有的排序方式添加到排序数组中NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"height" ascending:YES];// NSSortDescriptor的操作都是在SQLite层级完成的,不会将对象加载到内存中,所以对内存的消耗是非常小的request.sortDescriptors = @[sort];// 执行获取请求操作,获取的托管对象将会被存储在一个数组中并返回NSError *error = nil;NSArray<Employee *> *employees = [context executeFetchRequest:request error:&error];[employees enumerateObjectsUsingBlock:^(Employee * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { NSLog(@"Employee Name : %@, Height : %@, Brithday : %@", obj.name, obj.height, obj.brithday);}];// 错误处理if (error) { NSLog(@"CoreData Fetch Data Error : %@", error);}
这里设置
NSFetchRequest
对象的一些请求条件,设置查找Employee
表中name
为lxz
的数据,并且将所有符合的数据用height
值升序的方式排列。有实体关联关系
一个模型文件中的不同实体间,可以设置实体间的关联关系,这个在之前的文章中讲过。实体关联关系分为对一或对多,也可以设置是否双向关联。
这里演示的实体只是简单的
To One
的关系,并且下面会给出设置是否双向关联的区别对比。插入实体
// 创建托管对象,并将其关联到指定的MOC上Employee *zsEmployee = [NSEntityDescription insertNewObjectForEntityForName:@"Employee" inManagedObjectContext:context];zsEmployee.name = @"zhangsan";zsEmployee.height = @1.9f;zsEmployee.brithday = [NSDate date];Employee *lsEmployee = [NSEntityDescription insertNewObjectForEntityForName:@"Employee" inManagedObjectContext:context];lsEmployee.name = @"lisi";lsEmployee.height = @1.7f;lsEmployee.brithday = [NSDate date];Department *iosDepartment = [NSEntityDescription insertNewObjectForEntityForName:@"Department" inManagedObjectContext:context];iosDepartment.departName = @"iOS";iosDepartment.createDate = [NSDate date];iosDepartment.employee = zsEmployee;Department *androidDepartment = [NSEntityDescription insertNewObjectForEntityForName:@"Department" inManagedObjectContext:context];androidDepartment.departName = @"android";androidDepartment.createDate = [NSDate date];androidDepartment.employee = lsEmployee;// 执行存储操作NSError *error = nil;if (context.hasChanges) { [context save:&error];}// 错误处理if (error) { NSLog(@"Association Table Add Data Error : %@", error);}
上面创建了四个实体,并且将
Employee
都关联到Department
上,完成关联操作后通过MOC
存储到本地。可以看到上面所有的托管对象创建时,都使用
NSEntityDescription
的insert
方法创建,并和上下文建立关系。这时就想问了,我能直接采用传统的init
方法创建吗?会崩的
0 0
- 认识CoreData-使用进阶
- 认识CoreData-使用进阶
- 认识CoreData—使用进阶
- 认识CoreData—使用进阶
- iOS 认识CoreData-进阶
- 认识CoreData-基础使用
- CoreData—使用进阶
- 认识CoreData—基础使用
- 认识CoreData—基础使用
- 认识CoreData—基础使用
- 认识CoreData-初识CoreData
- CoreData进阶
- Coredata第一课 认识coredata
- Coredata第一课 认识coredata
- 认识CoreData—初识CoreData
- 认识CoreData—初识CoreData
- iOS进阶——coreData的使用与学习
- coreData初步认识
- jQuery自定义插件
- PyQt5教程(十)——自定义控件
- android之文件存储路径问题
- 在TextView中添加超链接
- 【opencv的学习】播放avi视频和视频播放控制
- 认识CoreData-使用进阶
- STA 进程内Com组件剖析
- 博弈_______Stone Game(hdu 4387)
- linux进程编程(三)-- execl()函数使用
- 分布式系统MIT 6.824学习资源
- 158.You want to create a role to meet these requirements: 1: The role is to be protected from unauth
- Object类
- test
- 玲珑学院-1010-Alarm【打表】【找规律】【思维】