我把常用的NSPredicate使用场景整理了一下
 
Cocoa提供了一个NSPredicate的类, 指定过滤方式筛选数据。
 
关于性能我做了个简单的测试,结果如下:
 
数据源500万条数据,计算时间基于5次试验的平均值

检索数据条数 For循环时间(秒) NSPredicate时间(秒)
1(位于数据源最后一项) 0.356625 1.487944
1(位于数据源前1000项) 0.002461 1.516057
6 1.763434 2.571393
12 3.466698 3.43019
24 6.58877 5.465602
48 12.699893 9.312682
96 25.36474 17.235685

从以上测试结果看,苹果对predicate的确做了优化,这种优化随着搜索数据集合的增加逐渐显现出来,

检索1条数据时,该数据在数据源中的位置对于Nspredicate来说基本没有影响;

搜索100条数据比for循环节省8秒钟时间,

但是搜索少量数据如1-10条以内的数据时,for循环还比较占优势  

下面整理一下常用方法:

NSPredicate有3种创建方式:格式化字符串/模板/代码方式,下面介绍3种方式

1.     使用格式化字符串创建

语法:NSPredicate *predicate = [NSPredicate predicateWithFormat: @"name == 'Herbie'"];
这里的格式化字符串方式比较丰富,可以用到多种运算符:
 
·      比较和逻辑运算符
==和=、>、>=和=>、<、<=和=<、!=和<>

AND、OR、NOT逻辑运算符或者C样式的等效表达式&&、||和!

示例:
predicate=[NSPredicate predicateWithFormat:@"(engine.horsepower>50) AND (engine.horsepower<200)"];


字符串中的运算符不区分大小写,你可以随意使用AnD、And或or,
不等号既适用于数字值又适用于字符串值;
另外注意表达式的写法支持KVC键路径
 
·      数组运算符
BETWEEN:

ü  predicate=[NSPredicate predicateWithFormat:@"engine.horsepower BETWEEN {50,200}"];

ü  NSArray *betweens=[NSArray arrayWithObjects:


                  [NSNumber numberWithInt:50],


                  [NSNumber numberWithInt:200],nil];


   predicate=[NSPredicate predicateWithFormat:@"engine.horsepower BETWEEN %@",betweens];

ü  predicateTemplate=[NSPredicate predicateWithFormat:@"engine.horsepower BETWEEN $POWERS"];


  varDict=[NSDictionary dictionaryWithObjectsAndKeys:betweens,@"POWERS",nil];


  predicate=[predicateTemplate predicateWithSubstitutionVariables:varDict];

IN:
	ü predicate=[NSPredicate predicateWithFormat:@"name IN {'Herbie','Snugs','Badger','Flap'}"];
    同理,IN也支持上面描述的between类型的构造方式
 
·      字符串运算符
 
    BEGINSWITH

    ENDSWITH

    CONTAINS

·      LIKE运算符

      通配符: ? 匹配单个字符 * 匹配任意个字符
NSPredicate *predicate = [NSPredicate
				predicateWithFormat:@"lastName like[c] \"S*\""];

·      正则表达式, MATCHES运算符

NSString *match = @"imagexyz-\\d{3}\\.png"; 

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF matches %@", match];

 
·     SELF关键字 
 
格式化字符串中除了使用对象的键路径引用属性,还可以使用
SELF关键字引用对象本身
predicate=[NSPredicate predicateWithFormat:@"SELF.name IN {'Herbie','Snugs','Badger','Flap'}"];
 
 ·    [c]、[d]或[cd]修饰符

  为了减少名称匹配规则,可以为这些运算符添加[c]、[d]或[cd]修饰符。其中,c表示“不区分大小写”,d表示“不区分发音符   号”,[cd]表示都不区分。

例如 "name BEGINSWITH[cd] 'HERB'"

·      ALL,ANY关键字

    对象存在关系对象时,有时还会用到ALL,ANY,指明本对象内的xx数组某一个或所有的需要满足xx条件
    [NSPredicate predicateWithFormat:@"ANY entryTags IN %@", selectedTags];
    [NSPredicate predicateWithFormat:@"ALL entryTags IN %@", selectedTags];

2.     使用Predicate 模板创建

     模板创建是基于字符串创建的,只不过提供了NSPredicate的模板实现方式
如果使用CoreData,可以使用Xcode的设计工具为Fetchrequest添加Predicate模板,详情可参考https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdMOM.html#//apple_ref/doc/uid/TP40002328
<632B09E1-5DB2-45E5-8A45-73E2B149B108.png>
 
当然,Predicate模板不仅仅是为CoreData服务的,可以实现自己的模板:
如上面的between运算符的第三种使用方式就是一种模板的实现
    NSArray *betweens = [NSArray arrayWithObjects:
                            [NSNumber numberWithInt: 50],
                            [NSNumber numberWithInt: 200], nil];
          NSPredicate* predicateTemplate = [NSPredicate predicateWithFormat: @"engine.horsepower BETWEEN $POWERS"];
           varDict = [NSDictionary dictionaryWithObjectsAndKeys: betweens, @"POWERS", nil];
          predicate = [predicateTemplate predicateWithSubstitutionVariables: varDict];

模板创建NSPredicate主要用于同样的过滤方式,不同的源数据情况下重用NSPredicate的情况使用。

3.     直接用代码创建

这种方式是直接使用predicate 和 expression创建NSPredicate,优点是没有使用到字符串解析等大量繁杂的字符串拼接方式,缺点是需要构造大量的expression对象,如下官网给出的实例:
 
NSExpression *lhs = [NSExpression expressionForKeyPath:@"revenue"];
 
NSExpression *greaterThanRhs = [NSExpression expressionForConstantValue:[NSNumber numberWithInt:1000000]];
 
NSPredicate *greaterThanPredicate = [NSComparisonPredicate
 
    predicateWithLeftExpression:lhs
 
    rightExpression:greaterThanRhs
 
    modifier:NSDirectPredicateModifier
 
    type:NSGreaterThanOrEqualToPredicateOperatorType
 
    options:0];
 
 
NSExpression *lessThanRhs = [NSExpression expressionForConstantValue:[NSNumber numberWithInt:100000000]];
 
NSPredicate *lessThanPredicate = [NSComparisonPredicate
 
    predicateWithLeftExpression:lhs
 
    rightExpression:lessThanRhs
 
    modifier:NSDirectPredicateModifier
 
    type:NSLessThanPredicateOperatorType
 
    options:0];
 
 
 
NSCompoundPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:
 
    @[greaterThanPredicate, lessThanPredicate]];

感觉这种方式用起来不太方便,也不太灵活,所以不继续深究了

IOS开发之--NSPredicate的更多相关文章

  1. iOS开发之--NSPredicate

    简述:Cocoa框架中的NSPredicate用于查询,原理和用法都类似于SQL中的where,作用相当于数据库的过滤取. 定义(最常用到的方法): NSPredicate *ca = [NSPred ...

  2. iOS开发系列--数据存取

    概览 在iOS开发中数据存储的方式可以归纳为两类:一类是存储为文件,另一类是存储到数据库.例如前面IOS开发系列-Objective-C之Foundation框架的文章中提到归档.plist文件存储, ...

  3. iOS开发之自定义表情键盘(组件封装与自动布局)

    下面的东西是编写自定义的表情键盘,话不多说,开门见山吧!下面主要用到的知识有MVC, iOS开发中的自动布局,自定义组件的封装与使用,Block回调,CoreData的使用.有的小伙伴可能会问写一个自 ...

  4. iOS开发之表视图爱上CoreData

    在接触到CoreData时,感觉就是苹果封装的一个ORM.CoreData负责在Model的实体和sqllite建立关联,数据模型的实体类就相当于Java中的JavaBean, 而CoreData的功 ...

  5. iOS开发常见BUG和一些小技巧(ps:耐心看完,很实用)

    [385][scrollView不接受点击事件,是因为事件传递失败] // // MyScrollView.m // Created by beyond on 15/6/6. // Copyright ...

  6. iOS开发200个tips总结(一)

    tip 1 :  给UIImage添加毛玻璃效果 func blurImage(value:NSNumber) -> UIImage { let context = CIContext(opti ...

  7. iOS开发中的4种数据持久化方式【二、数据库 SQLite3、Core Data 的运用】

                   在上文,我们介绍了ios开发中的其中2种数据持久化方式:属性列表.归档解档.本节将继续介绍另外2种iOS持久化数据的方法:数据库 SQLite3.Core Data 的运 ...

  8. iOS开发——面试指导

    iOS面试指导 一 经过本人最近的面试和对面试资料的一些汇总,准备记录这些面试题,以便ios开发工程师找工作复习之用,本人希望有面试经验的同学能和我同时完成这个模块,先出面试题,然后会放出答案. 1. ...

  9. IOS开发之NSPredicate谓词的用法

    编程的人员不管是上过大学还是从培训机构出来的或做后台的.前端的都应该SQL语句有所了解,我们知道,在SQL语句当中 where 条件表达式可以对二维关系表的数据做条件筛选.微软的C# .net中也实现 ...

  10. 【转】iOS 开发怎么入门?

    原文网址:http://www.zhihu.com/question/20264108 iOS 开发怎么入门? 请问有设计模式.内存管理方面的资料吗?最好有除了官方文档之外的其它内容,10 条评论 分 ...

随机推荐

  1. 第一个structs+spring+hibernate的web程序

    1. 数据库: Column Type Comment id int(11) Auto Increment   name varchar(50) NULL   url varchar(255) NUL ...

  2. Disable the screen switching about VI

    If you want to disable the screen switching, and you don't want tochange your termcap, you can add t ...

  3. business knowledge

    Finance knowledge Trading---At the core of our business model is Trading, which involves the buying ...

  4. DES带IV向量加密解密工具

    链接:http://pan.baidu.com/s/1kVAV80J  密码:sgys 鉴于网上的DES加密解密都是不带IV向量的 我就自制了一个带IV向量的DES加密解密的小工具 © 2016-20 ...

  5. 【Python】二分查找算法

    二分查找:在一段数字内,找到中间值,判断要找的值和中间值大小的比较.如果中间值大一些,则在中间值的左侧区域继续按照上述方式查找.如果中间值小一些,则在中间值的右侧区域继续按照上述方式查找.直到找到我们 ...

  6. Android开源益智游戏“斗地主”单机版源代码

     Android开源益智游戏"斗地主"单机版源代码 这是一个网上流传的Android开源斗地主单机版项目,运行结果如图: 项目源代码导入到Eclipse后可直接运行,我把ecl ...

  7. 通过git在github上建立gh-pages分支并查看网页效果

    建立gh-pages分支:    进入到你想要上传的文件夹下:           cd text(text为文件夹名)           git初始化           git init   创 ...

  8. C语言文件处理

    数据存储方式: 数据->变量->文件 数据 10个学生的信息: #define N 10 struct student { char stu_num[15]; char stu_name[ ...

  9. Project Woosah Tu (五色土)

    I bought this Raspberry Pi (model B) in spring 2013, I hadn't done too much with it except for some ...

  10. MSP430单片机的两种SPI总线实现方式

    MSP430单片机上的SPI总线的实现方式分为两种:硬件实现和软件实现. 二者的抽象层次不同,硬件实现方式下程序员只需要完成总线协议的寄存器层,即一字节(char,8位二进制)数据,而软件实现方式下程 ...