我们有些时候会有一个对象的数组或者集合,然后希望从里面找出符合条件的集合,类似于做一次过滤操作。比如我有一批照片,希望能找出所有某一天里面拍摄的内容。
NSPredicate类的创建往往使用predicateWithFormat的方法,这个方法的使用有点类似于stringWithFormat方法。
比如:我们想从一个目录下所有的文件中找出Default.png文件,那么
NSPredicate *predicate;
predicate = [NSPredicate predicateWithFormat: @"name == 'Default.png ' "];
这个谓词字符串看上去象标准的C表达式,左侧的name是键路径,随后的==是运算符,右侧是一个引用字符串。生成了谓词之后,如果你有一个对象希望判断一下是否符合条件,则使用evaluateWithObject方法
BOOL match = [predicate evaluateWithObject: file];
谓词最根本的功能就是这样,判定一个对象是否符合某个过滤条件,返回总是一个BOOL类型。如果你有一系列的对象,那么就做一个的循环即可。
当然,iOS的NSPredicate如果就这些功能,那么未免弱了点,有失顶级平台的风范。这个类有一系列的扩充:
1. 比较和逻辑运算符
就像前面的例子中使用了==操作符,NSPredicate还支持>, >=, <, <=, !=, <>,还支持AND, OR, NOT(或写成C语言样式&&, ||, ! ),其中AND,OR,NOT还是不区分大小写的
2. SELF和LIKE
请注意,这个并非iOS里面的self那个保留字。为什么会引入SELF这个东西呢?是因为不可能每次写谓词都有那么明确的键路径好用,而这个SELF可以引用用于谓词计算的对象。
LIKE运算符是用于通配符的支持,这个通配符就是?和*,这两个通配符应该是很熟悉的了。
有了这两个利器后,写谓词也是方便许多,比如我想匹配所有D打头的png文件,那么就是写
NSString *match = @"D*.png";
[NSPredicate predicateWithFormat:@"SELF LIKE %@", match];
3. 格式化
这个在上面的例子中已经出现了,支持格式化可以进一步提高编码的灵活度。
4. 正则表达式
谓词的表达式还支持正则表达式,记得我看见这个时都有点吃惊了。这样的话这个谓词的灵活可谓到了极致,如果写的比较好的话,可以实现相当复杂的过滤功能。
NSPredicate给我留下最深印象的是两个数组求交集的一个需求,如果按照一般写法,需要2个遍历,但NSArray提供了一个filterUsingPredicate的方法,用了NSPredicate,就可以不用遍历!
NSArray *array1 = [NSArray arrayWithObjects:@"abc1", @"abc2", nil];
NSArray *array2 = [NSArray arrayWithObjects:@"a1", @"abc1", @"abc4", @"abc2", nil];
NSPredicate *thePredicate = [NSPredicate predicateWithFormat:@"SELF in %@", array1];
[array2 filterUsingPredicate:thePredicate];
当你想从一批对象中过滤出一些内容时,请一定要记得NSPredicate这个东东哦