简介
NSPredicate提供了一个通用的数据查询方式,有两种Predicate类型,分别是comparison 和 compound:
- comparison predicate 使用运算符来比较两个表达式
- compound predicate 对比两个或多个predicate的结果,或者让其他的predicate 失效.
Cocoa 里支持非常多的 predicate 类型,例如:
- 简单的比较:
grade == 7
或者firstName like 'Mark'
- 大小写或读音敏感的查询:
name contains[cd] 'citroen'
- 逻辑操作符:
(firstName beginswith 'M') AND (lastName like 'Adderley')
你还可以根据关系创建predicate,例如:group.name matches 'work.*'
,ALL children.age > 12
以及ANY children.age > 12
根据操作创建例如:@sum.items.price < 1000
.
你可以把 predicates 用在任何类上,但这个类必须是遵循 key-value-coding 的类。
NSPredicate的局限
predicate查询可能会翻译成SQL语句或xml格式或者其他格式,这取决于后端存储的类型。因此并不是所有的操作后端存储都能支持。下面是一些例子:
matches
关键字使用正则来进行匹配,所以是不被CoreData的 SQL 存储支持的,但是却可以用在内存中的过滤。- CoreData SQL 存储里每次查询只能支持一对多的操作,因此任何应用在SQL存储的predicate都只能有
ALL
AND
IN
中的一个操作符。 - 不能将任意的SQL查询转换成predicate。
ANYKEY
操作符只能用在SpotLight的查询中。- SpotLight中不支持关系查询。
创建Predicate
使用格式化的字符串创建
可以使用NSPredicate的类方法
predicateWithFormat
从字符串创建一个predicate对象:NSPredicate* predicate = [NSPredicate predicateWithFormat: @"(lastName like[cd] %@) AND (birthday > %@)", lastNameSearchString, birthdaySearchDate];
示例代码中的
like[cd]
操作符表示大小写(c 表示case-insensitive,)发音(d 表示 diacritic-insensitive)不敏感。字符串常量、变量和通配符
字符串常量必须用引号包裹起来,用单引号或双引号都是可以的,如果你用%@来进行参数替换(例如
firstName like %@
),引号会自动添加,如果你用的是字符串常量,那你必须自己用引号包裹起来:NSPredicate* predicate = [NSPredicate predicateWithFormat: @"lastName like[c] 'S*'"]; // 或者 NSPredicate* predicate = [NSPredicate predicateWithFormat: @"lastName like[c] \"S*\""];
在使用通配符时必须考虑引号的问题,你应该把通配符添加到一个预定义的变量中来进行参数替换:
NSString* prefix = @"prefix"; NSString* suffix = @"suffix"; NSPredicate* predicate = [NSPredicate predicateWithFormat: @"SELF like[c] %@", [[prefix stringByAppendingString: @"*"] stringByAppendingString: suffix]]; BOOL o