Cocoa NSExpression 详解

简介: 每当涉及查询或者整理信息时,Cocoa总是其他标准库羡慕的对象。通过使用NSPredicate,NSSortDescriptor,以及偶尔使用NSFetchRequest,即使是最复杂的数据任务也可以被简化成为几行极其容易读懂的代码。

每当涉及查询或者整理信息时,Cocoa总是其他标准库羡慕的对象。通过使用NSPredicate,NSSortDescriptor,以及偶尔使用NSFetchRequest,即使是最复杂的数据任务也可以被简化成为几行极其容易读懂的代码。


现在,NSHipster们无疑已经熟悉NSPredicate 了,不过如果我们更进一步看看NSPredicate,我们会发现NSPredicate其实是由更小的部分而组成:两个NSExpression(一个左手值和一个右手值),和一个运算符相比较(比如<INLIKE等等)。

image.png

大多数开发者通过+predicateWithFormat:来使用NSPredicate,NSExpression是一个相对难懂的类。真可惜啊,因为NSExpression本身的功能非常强大。所以,亲爱的读者,请允许我来表达我对NSExpression深深的尊重和着迷:


评估数学

关于NSExpression你所要知道的第一件事就是它的主要目的是减少表达。如果你思考一下评估NSPredicate的过程,你会发现它有两个表达和一个比较符号,所以我们需要将两个表达简化为运算符可以处理的表达–非常像编译一行代码的过程。

这就是我们要学习的NSExpression的第一招: 做数学题。


NSExpression *expression = [NSExpression expressionWithFormat:@"4 + 5 - 2**3"];

id value = [expression expressionValueWithObject:nil context:nil]; // => 1

这并不是Wolfram Alpha,但是如果加入评估数学表达式对于你的应用很有用的话,那么…你就可以使用NSExpression。


函数

我们仅仅触及了NSExpression的表面。觉得一台电脑仅仅做小学数学不怎么厉害?那高中的统计学怎么样?

NSArray *numbers = @[@1, @2, @3, @4, @4, @5, @9, @11];

NSExpression *expression = [NSExpression expressionForFunction:@"stddev:"arguments:@[[NSExpression expressionForConstantValue:numbers]]];

id value = [expression expressionValueWithObject:nilcontext:nil]; // => 3.21859...

NSExpression 函数以给定数目的子表达式作为参数。比如,在上述例子中,要得到集合的标准差,数列中的数字要被+expressionForConstantValue:封装。虽然只是一个小小的不便(它最终却能使得NSExpression变得极其灵活),却足以使第一次尝试它的人绊倒。


如果你觉得键值编码简单集合运算符 (@avg,@sum等等)不够用,也许NSExpression的自带的统计,算术和位运算功能能激起你的兴趣。

要注意的是:根据Apple的NSExpression文档中的表格,很明显,Mac OS X & iOS的功能可用性之间没有重叠。看起来最近的iOS版本的确支持如stddev之类的函数,但这些变化并没有显示在头文件或者文档里。如果你注意到任何变化,请以pull request的形式告诉我,不胜感激。


统计

average:

sum:

count:

min:

max:

median:

mode:

stddev:


基本运算

这些函数需要用两个NSExpression对象来表达数字。

add:to:

from:subtract:

multiply:by:

divide:by:

modulus:by:

abs:

高级运算

sqrt:

log:

ln:

raise:toPower:

exp:


边界函数

ceiling: – (不小于数组中的值的最小积分值)

trunc: – (最接近但不大于数组中的值的积分值)

与math.h函数类似的函数

ceiling非常容易和ceil(3)混淆。ceiling作用于数字数组,而ceil(3)作用于一个double值(且它并没对应的内置NSExpression函数)。floor:在这里的作用和floor(3)一样。


随机函数

两个变量–一个带参数,一个不带参数。不带参数时,random返回rand(3)的等值,而random:则从NSExpression的数字数组中取任意元素。

random

random:

二进制运算

bitwiseAnd:with:

bitwiseOr:with:

bitwiseXor:with:

leftshift:by:

rightshift:by:

onesComplement:


日期函数

now


字符串函数

lowercase:

uppercase:


空操作

noindex:


自定义函数

除了这些内置的函数,你也可以在NSExpression中调用自定义函数。由Dave DeLong所撰写的这篇文章(Using custom functions with NSExpression ) 详述了这个过程。

首先,在类别中定义一个对应的函数:

@interface NSNumber (Factorial)

- (NSNumber *)factorial;

@end

@implementation NSNumber (Factorial)

- (NSNumber *)factorial {

   return @(tgamma([self doubleValue] + 1));

}

@end

然后,这样使用函数(+expressionWithFormat: 中的FUNCTION()宏是构造-expressionForFunction:等等的过程的简写。):

NSExpression *expression = [NSExpression expressionWithFormat:@"FUNCTION(4.2, 'factorial')"];

id value = [expression expressionValueWithObject:nil context:nil]; // 32.578...

这样的优势在于, 通过直接调用-factorial,我们可以调用NSPredicate查询中的函数。比如,我们可以定义一个location:withinRadius:方法来轻松的查询用户当前位置附近的管理对象。

正如Dave在他的文章中所提到的那样,这些用例十分边缘化,但它们肯定可以成为你的保留节目中有趣的技巧。

相关文章
|
9月前
|
Linux 网络安全 虚拟化
linux怎么把文件传到docker里面
在现代应用开发中,Docker作为流行的虚拟化工具,广泛应用于微服务架构。文件传输到Docker容器是常见需求。常用方法包括:1) `docker cp`命令直接复制文件;2) 使用`-v`选项挂载宿主机目录,实现数据持久化和实时同步;3) 通过SCP/FTP协议传输文件;4) 在Dockerfile中构建镜像时添加文件。选择合适的方法并确保网络安全是关键。
997 1
|
测试技术
黑盒测试、白盒测试、灰盒测试的区别和各自的目的
黑盒测试、白盒测试和灰盒测试是软件测试中常用的测试方法。它们的区别和各自的目的如下: 1. 黑盒测试(Black Box Testing): - 黑盒测试是一种功能性测试方法,使用者只关注输入和输出,不考虑内部结构和实现细节。 - 黑盒测试的目的是验证软件功能是否按照需求规格说明书的要求来执行。 - 测试人员不需要了解软件的内部逻辑和代码,只需关注输入和输出的正确性。 - 黑盒测试可通过设计测试用例,模拟用户使用软件的场景,以验证系统的正确性。 2. 白盒测试(White Box Testing): - 白盒测试是一种结构性测试方法,测试人员了解软件的内部结构
5398 0
|
2天前
|
数据采集 人工智能 安全
|
11天前
|
云安全 监控 安全
|
3天前
|
自然语言处理 API
万相 Wan2.6 全新升级发布!人人都能当导演的时代来了
通义万相2.6全新升级,支持文生图、图生视频、文生视频,打造电影级创作体验。智能分镜、角色扮演、音画同步,让创意一键成片,大众也能轻松制作高质量短视频。
1017 151
|
3天前
|
编解码 人工智能 机器人
通义万相2.6,模型使用指南
智能分镜 | 多镜头叙事 | 支持15秒视频生成 | 高品质声音生成 | 多人稳定对话
|
16天前
|
机器学习/深度学习 人工智能 自然语言处理
Z-Image:冲击体验上限的下一代图像生成模型
通义实验室推出全新文生图模型Z-Image,以6B参数实现“快、稳、轻、准”突破。Turbo版本仅需8步亚秒级生成,支持16GB显存设备,中英双语理解与文字渲染尤为出色,真实感和美学表现媲美国际顶尖模型,被誉为“最值得关注的开源生图模型之一”。
1710 9
|
8天前
|
人工智能 自然语言处理 API
一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸
一句话生成拓扑图!next-ai-draw-io 结合 AI 与 Draw.io,通过自然语言秒出架构图,支持私有部署、免费大模型接口,彻底解放生产力,绘图效率直接爆炸。
652 152
|
10天前
|
人工智能 安全 前端开发
AgentScope Java v1.0 发布,让 Java 开发者轻松构建企业级 Agentic 应用
AgentScope 重磅发布 Java 版本,拥抱企业开发主流技术栈。
619 12