402. nshipster-NSExpression
from iOSDevLog Hosted by iOSDevLog
http://nshipster.cn/nsexpression/ NSExpression Mattt Thompson撰写、 Zihan Xu翻译、 发布于2013年7月8日 每当涉及查询或者整理信息时,Cocoa总是其他标准库羡慕的对象。通过使用NSPredicate,NSSortDescriptor,以及偶尔使用NSFetchRequest,即使是最复杂的数据任务也可以被简化成为几行极其容易读懂的代码。 现在,NSHipster们无疑已经熟悉NSPredicate 了(如果你还不熟悉,下周一定要过来看看),不过如果我们更进一步看看NSPredicate,我们会发现NSPredicate其实是由更小的部分而组成:两个NSExpression(一个左手值和一个右手值),和一个运算符相比较(比如 1 这并不是Wolfram Alpha,但是如果加入评估数学表达式对于你的应用很有用的话,那么...你就可以使用NSExpression。 函数 我们仅仅触及了NSExpression的表面。觉得一台电脑仅仅做小学数学不怎么厉害?那高中的统计学怎么样? Objective-C NSArray *numbers = @[@1, @2, @3, @4, @4, @5, @9, @11]; NSExpression *expression = [NSExpression expressionForFunction:@"stddev:" arguments:@[[NSExpression expressionForConstantValue:numbers]]]; id value = [expression expressionValueWithObject:nil context:nil]; // => 3.21859... NSExpression 函数以给定数目的子表达式作为参数。比如,在上述例子中,要得到集合的标准差,数列中的数字要被+expressionForConstantValue:封装。虽然只是一个小小的不便(它最终却能使得NSExpression变得极其灵活),却足以使第一次尝试它的人绊倒。 如果你觉得 键值编码简单集合运算符 (@avg,@sum等等)不够用,也许NSExpression的自带的统计,算术和位运算功能能激起你的兴趣。 要注意的是:根据Apple的NSExpression文档中的表格,很明显,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)一样。 floor: 随机函数 两个变量--一个带参数,一个不带参数。不带参数时,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所撰写的这篇文章 详述了这个过程。 首先,在类别中定义一个对应的函数: Objective-C @interface NSNumber (Factorial) - (NSNumber *)factorial; @end @implementation NSNumber (Factorial) - (NSNumber *)factorial { return @(tgamma([self doubleValue] + 1)); } @end 然后,这样使用函数(+expressionWithFormat: 中的FUNCTION()宏是构造-expressionForFunction:等等的过程的简写。): Objective-C NSExpression *expression = [NSExpression expressionWithFormat:@"FUNCTION(4.2, 'factorial')"]; id value = [expression expressionValueWithObject:nil context:nil]; // 32.578... 这样的优势在于, 通过直接调用-factorial,我们可以调用NSPredicate查询中的函数。比如,我们可以定义一个location:withinRadius:方法来轻松的查询用户当前位置附近的管理对象。 正如Dave在他的文章中所提到的那样,这些用例十分边缘化,但它们肯定可以成为你的保留节目中有趣的技巧。. 下一周,我们将在刚刚学过的NSExpression的基础上继续探索NSPredicate和其它一切容易被忽视的内容。敬请期待! 作者 Mattt ThompsonMattt Thompson Mattt Thompson (@mattt) is the creator & maintainer of AFNetworking and other popular open-source projects, including Postgres.app, ASCIIwwdc and Nomad. 翻译者 Zihan Xu 下一篇文章 NSPredicate NSPredicate是一个Foundation类,它指定数据被获取或者过滤的方式。它的查询语言就像SQL的WHERE和正则表达式的交叉一样,提供了具有表现力的,自然语言界面来定义一个集合被搜寻的逻辑条件。 相关文章 UIReferenceLibraryViewController / DCSDictionaryRef NSURLCache Search Kit NSURLProtocol 除非另有声明、本网站采用知识共享「署名-非商业性使用 3.0 中国大陆」许可协议授权。 本站文章由 Croath Liu 、 、 Delisa Mason 、 Jack Flintermann 、 Mattt Thompson 、 、 Mike Lazer-Walker 、 Natasha Murashev 和 Nate Cook 撰写、 Andrew Yang 、 April Peng 、 Bob Liu 、 Candyan 、 Chester Liu 、 Croath Liu 、 David Liu 、 GWesley 、 Henry Lee 、 JJ Mao 、 Lin Xiangyu 、 Ricky Tan 、 Sheldon Huang 、 Tiny Tian 、 Tony Li 、 Yifan Xiao 、 Yu Jin 和 Zihan Xu 翻译。
Embed this episode
No transcript yet.