我把常用的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. MainWindow、QWidget和QDialog的区别和选择(转载)

    QApplication类用于管理应用程序范围内的资源,其构造函数需要main函数的argc和argv作为参数. Widget被创建时都是不可见的,widget中可容纳其他的widget. Qt中的w ...

  2. [解决方案] pythonchallenge level 0

    http://www.pythonchallenge.com/pc/def/0.html 问题: 2^38 >>> 2**38 >>>274877906944L 输 ...

  3. 【转】VS2010安装后出现无法使用帮助的解决方案

    安装完VS2010后 再安装MSDN 打开“Help Library 管理器 - Microsoft Help 查看器 1.0” 提示“请为本地内容选择位置” 默认的位置是在“C:/Documents ...

  4. C++ Daily 《6》---- 类静态对象与函数静态对象

    C++ 的一个哲学基础是,你不应该为你使用的东西付出代价. class 拥有一个 static 成员,即使从未被用到,它也会被构造和析构: 而 函数拥有一个 static 成员, 如果这个函数从未被调 ...

  5. PHP开发调试环境配置(基于wampserver+Eclipse for PHP Developers )

    1 软件准 WampServer 下载地址:http://www.wampserver.com/en/#download-wrapper    我下的是 里面包含了搭建PHP必须的4个软件:   1. ...

  6. Git 的深入理解与GitHub托管服务(转)

    源代码管理系统(SCM)与版本控制   版本控制是一种记录若干文件内容变化,以便将来查阅特定版本修订情况的系统.   本地版本控制系统   许多人习惯用复制整个项目目录的方式来保存不同的版本,或许还会 ...

  7. flash2x、flax

    http://flax.so/ 牛客网 LeetCode Online Judge

  8. 浏览器 私有属性&内核

    -moz代表firefox浏览器私有属性 -ms代表IE浏览器私有属性 -webkit代表chrome.safari私有属性 IE使用的是Trident内核,Firefox 使用的是Gecko内核.目 ...

  9. (利用tempdata判断action是直接被访问还是重定向访问)防止微信活动中用户绕过关注公众号的环节

    说明:这个不是在进行微信公众号开发,也就是说在不能获取用户openid的前提下做的下面操作 1.动机:最近有个微信活动(关注了服务号的可以免费领取礼品),要做这么一个功能,活动的入口在微信服务号的菜单 ...

  10. [转]Jenkins使用 管理节点

    现在我们已经搭建好了基本的Jenkins环境,在这一集里,我们说一说如何管理节点. 进入“系统管理”中的“管理节点”. 创建Windos系统的奴隶节点 先创建一台安装了Win7系统的虚拟机,作为Jen ...