Cocoa提供了一个名为NSPredicate的类,它用于指定过滤器的条件。可以创建NSPredicate对象,通过该对象准确地描述所需的条件,对每个对象通过谓词进行筛选,判断它们是否与条件相匹配。

这里的“谓词”通常用在数学和计算机科学概念中,表示计算真值或假值的函数。

Cocoa用NSPredicate描述查询的方式,原理类似于在数据库中进行查询。可

以在数据库风格的API中使用NSPredicate,例如Core Data 和

Spotlight。可以将NSPredicate看成另一种间接操作方式。例如,如果需要查询满足条件的机器人,可以使用谓词对象进行检查,而不必使用

代码进行显式查询。通过交换谓词对象,可以使用通用代码对数据进行过滤,而不必对相关条件进行硬编码。

创建谓词

在将NSPredicate应用于某个对象之前,首先需要创建它。可以通过两种基本方式

来实现。第一种是创建许多对象,并将它们组合起来。这需要使用大量代码,如果正在构建通用用户接口来指定查询,采用这种方式比较简单。另一种方式是查询代

码中的字符串。对初学者来说,这种方式比较简单。因此,本章重点介绍查询字符串。常见的面向字符串的API警告信息适用于查询字符串,特别适用于缺少编译

器错误检查及有时出现奇怪的运行时错误等情况。

Car *car =

makeCare(@”Herbie”,@”Honda”,@”CRX”,1984,2,110000,58);

[garage addCare:car];

构造了一辆汽车,品牌是Herbie,型号为双门1984 Honda

CRX,马力引擎为58,已行驶距离为110000英里。

现在创建谓词:

NSPredicate *predicate;

predicate = [NSPredicate

predicateWithFormat:@”name==‘Herbie’”];

我们将以上代码拆开分析。predicate是一个常用的Objective-C对象指

针,它将指向NSPredicate对象。使用NSPredicate类方法+predicateWithFormat:来实际创建谓词。将某个字符串赋

值给谓词,+predicateWithFormat:使用该字符串在后台构建对象树,这些树用来计算谓词的值。

这种谓词字符串看上去像是标准的C表达式。它的左侧是键路径name,随后是一个等于运

算符“==”,右侧是一个引用字符串。如果谓词字符串中的文本块未被引用,则该谓词字符串被看做是键路径;如果引用了文本块,则认为它是文本字符串。你可

以使用单引号或者双引号。通常应该使用单引号;否则,必须在字符串中对每个双引号进行转义。

计算谓词

我们将通过某个对象计算谓词

BOOL match = [predicate

evaluateWithObject:car];

NSLog(@”%s”,match ?

“YES”:”NO”);

-evaluateWithObject:通知接收对象(谓词)根据指定的对象计算自身

的值。在本例中,接收对象为car,使用name作为键路径,应用valueForKeyPath:方法获取名称。然后,它将自身的值(即名称)与

“Herbie”相比较。如果名称和“Herbie”相同,则-evaluateWithObject:返回YES,否则返回NO。此处,NSLog使用

三元运算符将数值BOOL转换成人们可读的字符串形式。

以下是另一个谓词:

predicate = [NSPredicate

predicateWithFormat:@”engine.horsepower >

150”];

match = [predicate

evlueateWithObject:car];

此谓词字符串左侧是一个键路径。该键路径链接到汽车内部,查找引擎,然后查询引擎的马力。接下来,它将马力值与150进行比较。

通过特定的谓词条件检查单个对象时进展都很顺利,如果需要检查对象集合,情况就会变得更加有趣。假设我们需要查看车库中哪些汽车的功率最大,可以循环测试每个汽车的谓词:

NSArray *cars = [garage

cars];

for(Car car in cars){

if([predicate

evaluateWithObject:car]){

NSLog(@“%@”,car.name);

}

}

燃料过滤器

如果我们不必编写for循环和if语句,这有什么不好吗?程序中仅有几个代码行,但不包含代码就更好了。幸运的是,某些类别将谓词过滤方法添加到了Cocoa集合类中。

-filteredArrayUsingPredicate:是NSArray数组中的一种类别方法,它将循环过滤数组内容,根据谓词计算每个对象的值,并将值为YES的对象累积到将被返回的新数组中:

NSArray *results;

results = [cars

filteredArrayUsingPredicate:predicate];

以上这些结果同前面的结果不一样。这里是一组汽车;前面的示例中,我们得到的结果是名称。我们可以使用KVC提取其中的名称。

假设有一个可变数组,你需要剔除不属于该数组的所有项目。NSMutableArray具有-filterUsingPredicate方法,它能轻松实现你的目标:

NSMutableArray *carsCopy = [cars

mutableCopy];

[carCopy

filterUsingPredicate:predicate];

也可以使用-filteredArrayUsingPredicate:。

我们在讨论KVC时提到过,使用谓词确实很便捷,但它的运行速度不会比你自己编写全部代码快。因为它无法避免在所有汽车之间使用循环和对每辆汽车进行某些操作。一般来说,这种循环并不会带来很大的性能影响,因为当今的计算机运行速度非常快。

格式说明符

可以通过两种方式将不同的内容放入谓词格式字符串中:格式说明符和变量名。首先,我们将介绍格式说明符。可以在你熟知的%d和%f格式说明符中使用数字形式的值:

predicate = [NSPredicate

predicateWithFormat:@”engine.horsepower >

%d”,50];

当然,我们一般不直接在代码中使用值50,可以通过用户接口或某些扩展机制来驱动它。

队了使用printf说明符,也可以使用%@插入字符串值,将%@看成是一个引用字符串:

predicate = [NSPredicate

predicateWithFormat:@”name==%@”,@”Herbie”];

注意,这里的格式字符串中没有引用%@。如果你需要引用%@,例如“name==’%@’”,应该将字符%和@放在谓词字符串中。

通过NSPredicate字符串,也可以使用%K指定键路径。该谓词和其它谓词相同,使用name==‘Herbie’作为条件:

predicate = [NSPredicate

predicateWithFormat:@”%K == %@”,@”name”,@”Herbie”];

为了构造灵活的谓词,一种方式是使用格式说明符,另一种方式是将变量名放入字符串中,类似于环境变量:

NSPredicate *predicateTemplate =

[NSPredicate predicateWithFormat:@”name==$NAME”];

现在,我们有一个含有变量的谓词。接下来,可以使用predicateWithSubstitutionVariables调用来构造新的专用谓词。创建一个键/值对字典,其中,键是变量名,值是插入谓词的内容:

NSDictionary *varDict;

varDict = [NSDictionary

dictionaryWithObjectsAndKeys:@”Herbie”,@”NAME”,nil];

这里使用字符串”Herbie”作为键“NAME”的值。因此,构造以下形式的新谓词:

predicate = [predicateTemplate

predicateWithSubstitutionVariables:varDict];

该谓词的工作方式和你所见过的其它谓词完全相同。

谓词运算符

>大于

>=和=>大于或等于

<=和=

!=和<>不等于

此外,谓词字符串语法还支持括号表达式和AND、OR、NOT逻辑运算符或者C样式的等效表达式&&、||和!。

谓词字符串中的运算符不区分大小写。

不等号即适用于数字值又适用于字符串值。

数组运算符

predicate = [NSPredicate

predicateWithFormat:@”engine.horsepower BETWEEN

{50,200}”];

花括号表示数组,BETWEEN将数组中每个元素看成是数组的下界,第二个元素看成是数组的上界。

IN

predicate = [NSPredicate

predicateWithFormat:@”name IN

{‘Herbia’,‘Snugs’,‘Flap’}”];

SELF

SELF

可以引用用于谓词计算的对象。我们可以将谓词中所有的键路径表示成对应的SELF。此谓词和前面的谓词完全相同:

[predicate = NSPredicate

predicateWithFormat:@”SELF.name in

{‘Herbia’,‘Snugs’,‘Flap’}”];

字符串运算符

BEGINSWITH

检查某个字符串是否以另一个字符串开头。

ENDSWITH

检查某个字符串是否以另一个字符串结尾。

CONTAINS

检查某个字符串是否在另一个字符串内部。

例,使用“name BEGINWITH

‘Bad’”匹配”Badger”,使用”name ENDSWITH ‘vis’”匹配“Elvis”,使用”name CONTAINS

udg”匹配“Judge”。

字符串匹配区分大小写。

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

LIKE运算符

谓词字符串“name LIKE

‘*er*’”将会与任何含有”er”的名称相匹配。这等效于CONTAINS。谓词字符串“name LIKE

‘???er*’”将会匹与Paper Car 相匹配,一个?代表一个字符。

java objective-c,Objective-C基础教程学习笔记(附录)从Java转向Objective-C相关推荐

  1. 黑马程序员最新版JavaWeb基础教程-学习笔记

    da@黑马程序员最新版JavaWeb基础教程-学习笔记 day06-HTML&CSS HTML HTML(HyperTest Markup Language):超文本标记语言 是一门语言,所有 ...

  2. linux磁盘符变化autofs,Linux基础教程学习笔记之Autofs自动挂载

    Linux基础教程学习笔记之Autofs自动挂载 Autofs自动挂载: yum -y install autofs vim /etc/auto.master  在文件中添加下面行 /home/gue ...

  3. 网络存储 linux 访问,Linux基础教程学习笔记28——使用Samba访问网络存储

    Linux基础教程学习笔记28--使用Samba访问网络存储 SMB用于Windows和类Linux系统直接的文件共享 安装samba client包: [root@linuxidc~]# yum i ...

  4. Python基础教程学习笔记:第一章 基础知识

    Python基础教程 第二版 学习笔记 1.python的每一个语句的后面可以添加分号也可以不添加分号:在一行有多条语句的时候,必须使用分号加以区分 2.查看Python版本号,在Dos窗口中输入&q ...

  5. 【莫烦Python】Python 基础教程——学习笔记

    文章目录 本笔记基于p1-p29[莫烦Python]Python 基础教程 大家可以根据代码内容和注释进行学习. 安装 我的:python3.8+anaconda+VS code print() pr ...

  6. Learn the object-c on MAC(中译本: Object-C 基础教程 ) 学习笔记

    [comments to this book]Object-C 基础教程 这本书翻译的水平很高,浅显易懂. 隐藏的self. 在使用instance method的时候,self会隐含的指向接收消息的 ...

  7. 二十一世纪大学英语读写基础教程学习笔记(原文)——5 - Shipwrecked in Antarctica(沉船南极洲)

    Unit 5 - Shipwrecked in Antarctica(沉船南极洲) Ernest Shackleton made many great achievements in his life ...

  8. 二十一世纪大学英语读写基础教程学习笔记(原文)——10 - The Future(未来)

    Unit 10 - The Future(未来) What will our future be like? What might happen in the year 2144? How far c ...

  9. 二十一世纪大学英语读写基础教程学习笔记(原文)——2 - It‘s a New Day(新的一天)

    Unit 2 - It's a New Day!(新的一天) In the following text, the writer tells us how we can manage to face ...

  10. python机器学习基础教程-学习笔记(一)

    了解 scikit-learn 及其用法是很重要的,但还有其他一些库也可以改善你的编程体验. scikit-learn 是基于 NumPy 和 SciPy 科学计算库的.此外,我们还会用到 panda ...

最新文章

  1. 编程软件python中的if用法-Python高效编程的19个技巧
  2. python中可以用中文作为变量-Python中用中文变量名、函数名,会影响性能吗?
  3. Java Review - ArrayList 源码解读
  4. 8.Boost之unordered_set
  5. python3 Async/Await入门指南
  6. NSInteger,NSUInteger,NSNumber
  7. matlab中ahp方法,AHP及matlab程序.doc
  8. 固态硬盘怎么看出厂日期_固态到底怎么选?雷克沙NM610和西部数据SN500固态硬盘实测对比...
  9. 滴滴滴,测试工程师简历模板分享一波
  10. 我通过了 Google 技术面试,所以你也能行!
  11. 阿迪达斯asp.net sql购物商城计算机设计网站作品
  12. malloc函数用法
  13. 如何设置eclipse眼睛保护色-码农必备
  14. 怎样将OFD转成PDF并保留电子签章
  15. Android自定义Behavior
  16. HTML中abbr标记,HTML abbr标记
  17. Kafka or RabbitMQ:消息中间件选型深入分析
  18. 如何在office2016(word2016)中安装mathtype6.9及相关问题解决方案
  19. NB-IoT智能配电柜测温监测系统解决方案
  20. 一份标准的软件测试计划文档 | 新手可以拿走

热门文章

  1. Linux 命令(123)—— iostat 命令
  2. 多益网络 2016 春季实习校招笔试回顾(C++游戏后台)
  3. C++ 抛出和接收异常的顺序
  4. C++ 数据类型转换详解之终极无惑
  5. 单调栈求全1(或全0)子矩阵的个数 洛谷P5300与或和 P3400仓鼠窝
  6. 利用sdkman安装kotlin和java环境
  7. Maven教程:tutorialspoint-maven
  8. 【Coding】C++诡异问题之一
  9. 一个通配符引起的错误
  10. 第三节:SpringBoot中web项目推荐目录结构