1葛闷、Creating Predicates

There are three ways to create a predicate in Cocoa: using a format string, directly in code, and from a predicate template.

  • 在Cocoa中有三種創(chuàng)建謂詞的方法:使用格式字符串赎败,直接在代碼中角钩,以及從謂詞模板中使用。

Creating a Predicate Using a Format String

You can use NSPredicate class methods of the form predicateWithFormat… to create a predicate directly from a string. You define the predicate as a string, optionally using variable substitution. At runtime, variable substitution—if any—is performed, and the resulting string is parsed to create corresponding predicate and expression objects. The following example creates a compound predicate with two comparison predicates.

  • 您可以使用形式predicateWithFormat ...的NSPredicate類方法直接從字符串創(chuàng)建謂詞爬坑。 您可以將謂詞定義為字符串纠屋,也可以使用變量替換。 在運行時盾计,執(zhí)行變量替換(如果有)售担,并解析生成的字符串以創(chuàng)建相應的謂詞和表達式對象。 以下示例使用兩個比較謂詞創(chuàng)建復合謂詞署辉。
NSPredicate *predicate = [NSPredicate
    predicateWithFormat:@"(lastName like[cd] %@) AND (birthday > %@)",
            lastNameSearchString, birthdaySearchDate];

(In the example, like[cd] is a modified “l(fā)ike” operator that is case-insensitive and diacritic-insensitive.) For a complete description of the string syntax and a list of all the operators available, see Predicate Format String Syntax.
-(在示例中族铆,like[cd]是一個不區(qū)分大小寫且對變音不敏感的修改后的“l(fā)ike”運算符。)有關字符串語法的完整說明以及所有可用運算符的列表涨薪,請參閱謂詞格式字符串語法骑素。

Important: The predicate format string syntax is different from the regular expression syntax. The regular expression syntax is defined by the ICU—see http://www.icu-project.org/userguide/regexp.html.

The predicate string parser is whitespace insensitive, case insensitive with respect to keywords, and supports nested parenthetical expressions. It also supports printf-style format specifiers (like %x and %@)—see Formatting String Objects. Variables are denoted with a $ (for example $VARIABLE_NAME)—see Creating Predicates Using Predicate Templates for more details.

  • 謂詞字符串解析器對空格不敏感,對關鍵字不區(qū)分大小寫末捣,并支持嵌套的括號表達式侠姑。 它還支持printf樣式的格式說明符(如%x和%@) - 請參閱格式化字符串對象。變量用$表示(例如$ VARIABLE_NAME) - 請參閱使用謂詞模板創(chuàng)建謂詞以獲取更多詳細信息箩做。

The parser does not perform any semantic type checking. It makes a best-guess effort to create suitable expressions, but—particularly in the case of substitution variables—it is possible that a runtime error will be generated.

  • 解析器不執(zhí)行任何語義類型檢查莽红。 它可以最大限度地嘗試創(chuàng)建合適的表達式,但是 - 特別是在替換變量的情況下 - 可能會生成運行時錯誤邦邦。

This approach is typically best used for predefined query terms, although variable substitution allows for considerable flexibility. The disadvantage of this technique is that you must take care to avoid introducing errors into the string—you will not discover mistakes until runtime.

  • 這種方法通常最適用于預定義的查詢術語安吁,盡管變量替換允許相當大的靈活性。 這種技術的缺點是你必須注意避免在字符串中引入錯誤 - 在運行之前你不會發(fā)現(xiàn)錯誤燃辖。

String Constants, Variables, and Wildcards

  • 字符串常量鬼店,變量和通配符

String constants must be quoted within the expression—single and double quotes are both acceptable, but must be paired appropriately (that is, a double quote (") does not match a single quote (')). If you use variable substitution using %@ (such as firstName like %@), the quotation marks are added for you automatically. If you use string constants within your format string, you must quote them yourself, as in the following example.

  • 字符串常量必須在表達式中引用 - 單引號和雙引號都是可接受的,但必須適當配對(即雙引號(“)與單引號(')不匹配黔龟。)如果使用變量替換請使用%@(例如firstName妇智,如%@),引號會自動添加氏身。如果在格式字符串中使用字符串常量巍棱,則必須自己引用它們,如下例所示蛋欣。
NSPredicate *predicate = [NSPredicate
    predicateWithFormat:@"lastName like[c] \"S*\""];

You must take automatic quotation into account when using wildcards—you must add wildcards to a variable prior to substitution, as shown in the following example.

  • 使用通配符時必須考慮自動引用 - 必須在替換之前將通配符添加到變量航徙,如以下示例所示。
NSString *prefix = @"prefix";
NSString *suffix = @"suffix";
NSPredicate *predicate = [NSPredicate
    predicateWithFormat:@"SELF like[c] %@",
    [[prefix stringByAppendingString:@"*"] stringByAppendingString:suffix]];
BOOL ok = [predicate evaluateWithObject:@"prefixxxxxxsuffix"];

In this example, variable substitution produces the predicate string SELF LIKE[c] "prefix*suffix", and the value of ok is YES. The following fragment, by contrast, yields the predicate string SELF LIKE[c] "prefix" * "suffix", and the predicate evaluation yields a runtime error:

  • 在此示例中陷虎,變量替換生成謂詞字符串SELF LIKE [c]“prefix * suffix”到踏,ok的值為YES倒得。 相反,以下片段產(chǎn)生謂詞字符串SELF LIKE [c]“prefix”*“suffix”夭禽,謂詞評估產(chǎn)生運行時錯誤:
predicate = [NSPredicate
    predicateWithFormat:@"SELF like[c] %@*%@", prefix, suffix];
ok = [predicate evaluateWithObject:@"prefixxxxxxsuffix"];

Finally, the following fragment results in a runtime parse error (Unable to parse the format string "SELF like[c] %@*").

  • 最后霞掺,以下片段導致運行時解析錯誤(無法解析格式字符串“SELF like [c]%@ *”)。
predicate = [NSPredicate
    predicateWithFormat:@"SELF like[c] %@*", prefix];

You should also note the difference between variable substitution in the format string and variable expressions. The following code fragment creates a predicate with a right-hand side that is a variable expression.

  • 您還應該注意格式字符串和變量表達式中的變量替換之間的區(qū)別讹躯。 以下代碼片段創(chuàng)建一個謂詞菩彬,其右側是變量表達式。
predicate = [NSPredicate
    predicateWithFormat:@"lastName like[c] $LAST_NAME"];

For more about variable expressions, see Creating Predicates Using Predicate Templates.

  • 有關變量表達式的更多信息潮梯,請參閱使用謂詞模板創(chuàng)建謂詞骗灶。

Boolean Values

You specify and test for equality of Boolean values as illustrated in the following examples:

  • 您可以指定并測試布爾值的相等性,如以下示例所示:
NSPredicate *newPredicate  = 
    [NSPredicate predicateWithFormat:@"anAttribute == %@", 
          [NSNumber numberWithBool:aBool]];

NSPredicate *testForTrue =
     [NSPredicate predicateWithFormat:@"anAttribute == YES"];

Dynamic Property Names

Because string variables are surrounded by quotation marks when they are substituted into a format string using %@, you cannot use %@ to specify a dynamic property name—as illustrated in the following example.

  • 因為字符串變量在使用%@替換為格式字符串時會被引號括起來秉馏,所以不能使用%@來指定動態(tài)屬性名稱 - 如以下示例所示耙旦。
NSString *attributeName = @"firstName";
NSString *attributeValue = @"Adam";
NSPredicate *predicate = 
    [NSPredicate predicateWithFormat:@"%@ like %@",
               attributeName, attributeValue];

The predicate format string in this case evaluates to "firstName" like "Adam".

  • 在這種情況下,謂詞格式字符串的計算結果為“firstName”萝究,like “Adam”免都。

If you want to specify a dynamic property name, you use %K in the format string, as shown in the following fragment.

  • 如果要指定動態(tài)屬性名稱,請在格式字符串中使用%K帆竹,如以下片段所示绕娘。
predicate = [NSPredicate predicateWithFormat:@"%K like %@",
        attributeName, attributeValue];

The predicate format string in this case evaluates to firstName like "Adam" (note that there are no quotation marks around firstName).

  • 在這種情況下,謂詞格式字符串的計算結果為firstName栽连,like “Adam”(請注意firstName周圍沒有引號)险领。

Creating Predicates Directly in Code

You can create predicate and expression instances directly in code. NSComparisonPredicate and NSCompoundPredicate provide convenience methods that allow you to easily create compound and comparison predicates respectively. NSComparisonPredicate provides a number of operators ranging from simple equality tests to custom functions.

  • 您可以直接在代碼中創(chuàng)建謂詞和表達式實例。 NSComparisonPredicate和NSCompoundPredicate提供了方便的方法秒紧,使您可以分別輕松創(chuàng)建復合謂詞和比較謂詞绢陌。 NSComparisonPredicate提供了許多運算符,從簡單的相等性測試到自定義函數(shù)熔恢。

The following example shows how to create a predicate to represent (revenue >= 1000000) and (revenue < 100000000). Note that the same left-hand side expression is used for both comparison predicates.

  • 以下示例顯示如何創(chuàng)建謂詞以表示(收入> = 1000000)和(收入<100000000)脐湾。 請注意,兩個比較謂詞都使用相同的左側表達式绩聘。
NSExpression *lhs = [NSExpression expressionForKeyPath:@"revenue"];
 
NSExpression *greaterThanRhs = [NSExpression expressionForConstantValue:[NSNumber numberWithInt:1000000]];
NSPredicate *greaterThanPredicate = [NSComparisonPredicate
    predicateWithLeftExpression:lhs
    rightExpression:greaterThanRhs
    modifier:NSDirectPredicateModifier
    type:NSGreaterThanOrEqualToPredicateOperatorType
    options:0];
 
NSExpression *lessThanRhs = [NSExpression expressionForConstantValue:[NSNumber numberWithInt:100000000]];
NSPredicate *lessThanPredicate = [NSComparisonPredicate
    predicateWithLeftExpression:lhs
    rightExpression:lessThanRhs
    modifier:NSDirectPredicateModifier
    type:NSLessThanPredicateOperatorType
    options:0];
 
NSCompoundPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:
    @[greaterThanPredicate, lessThanPredicate]];

The disadvantage of this technique should be immediately apparent—you may have to write a lot of code. The advantages are that it is less prone to spelling and other typographical errors that may only be discovered at runtime and it may be faster than depending on string parsing.

  • 這種技術的缺點應該是顯而易見的 - 您可能需要編寫大量代碼沥割。 優(yōu)點是它不易于拼寫和其他印刷錯誤,這些錯誤只能在運行時發(fā)現(xiàn)凿菩,而且可能比依賴字符串解析更快机杜。

This technique is most likely to be useful when the creation of the predicate is itself dynamic, such as in a predicate builder.

  • 當謂詞的創(chuàng)建本身是動態(tài)的時,這種技術最有用衅谷,例如在謂詞構建器中椒拗。

Creating Predicates Using Predicate Templates

Predicate templates offer a good compromise between the easy-to-use but potentially error-prone format string-based technique and the code-intensive pure coding approach. A predicate template is simply a predicate that includes a variable expression. (If you are using the Core Data framework, you can use the Xcode design tools to add predicate templates for fetch requests to your model—see Managed Object Models.) The following example uses a format string to create a predicate with a right-hand side that is a variable expression.

  • 謂詞模板在易于使用但可能容易出錯的基于字符串的格式技術與代碼密集型純編碼方法之間提供了良好的折衷。 謂詞模板只是一個包含變量表達式的謂詞。 (如果您使用的是Core Data框架蚀苛,則可以使用Xcode設計工具為模型添加獲取請求的謂詞模板 - 請參閱托管對象模型在验。)以下示例使用格式字符串創(chuàng)建帶右側的謂詞 這是一個變量表達式。
NSPredicate *predicateTemplate = [NSPredicate
    predicateWithFormat:@"lastName like[c] $LAST_NAME"];

This is equivalent to creating the variable expression directly as shown in the following example.

  • 這相當于直接創(chuàng)建變量表達式堵未,如以下示例所示腋舌。
NSExpression *lhs = [NSExpression expressionForKeyPath:@"lastName"];
 
NSExpression *rhs = [NSExpression expressionForVariable:@"LAST_NAME"];
 
NSPredicate *predicateTemplate = [NSComparisonPredicate
    predicateWithLeftExpression:lhs
    rightExpression:rhs
    modifier:NSDirectPredicateModifier
    type:NSLikePredicateOperatorType
    options:NSCaseInsensitivePredicateOption];

To create a valid predicate to evaluate against an object, you use the NSPredicate method predicateWithSubstitutionVariables: to pass in a dictionary that contains the variables to be substituted. (Note that the dictionary must contain key-value pairs for all the variables specified in the predicate.)

  • 要創(chuàng)建有效的謂詞來評估對象,可以使用NSPredicate方法predicateWithSubstitutionVariables:傳入包含要替換的變量的字典渗蟹。 (請注意块饺,字典必須包含謂詞中指定的所有變量的鍵值對。)
NSPredicate *predicate = [predicateTemplate predicateWithSubstitutionVariables:
    [NSDictionary dictionaryWithObject:@"Turner" forKey:@"LAST_NAME"]];

The new predicate returned by this example is lastName LIKE[c] "Turner".

  • 此示例返回的新謂詞是lastName LIKE [c]“Turner”雌芽。

Because the substitution dictionary must contain key-value pairs for all the variables specified in the predicate, if you want to match a null value, you must provide a null value in the dictionary, as illustrated in the following example.

  • 因為替換字典必須包含謂詞中指定的所有變量的鍵值對授艰,所以如果要匹配空值,則必須在字典中提供空值世落,如以下示例所示淮腾。
NSPredicate *predicate = [NSPredicate
    predicateWithFormat:@"date = $DATE"];
predicate = [predicate predicateWithSubstitutionVariables:
    [NSDictionary dictionaryWithObject:[NSNull null] forKey:@"DATE"]];

The predicate formed by this example is date == <null>.

  • 這個例子形成的謂詞是date == <null>

Format String Summary

It is important to distinguish between the different types of value in a format string. Note also that single or double quoting variables (or substitution variable strings) will cause %@, %K, or $variable to be interpreted as a literal in the format string and so will prevent any substitution.

  • 區(qū)分格式字符串中的不同類型的值很重要屉佳。 另請注意谷朝,單引號或雙引號變量(或替換變量字符串)將導致%@,%K或$變量被解釋為格式字符串中的文字忘古,因此將阻止任何替換徘禁。

@"attributeName == %@"
This predicate checks whether the value of the key attributeName is the same as the value of the object %@ that is supplied at runtime as an argument to predicateWithFormat:. Note that %@ can be a placeholder for any object whose description is valid in the predicate, such as an instance of NSDate, NSNumber, NSDecimalNumber, or NSString.

  • 此謂詞檢查鍵attributeName的值是否與在運行時作為predicateWithFormat:的參數(shù)提供的對象%@的值相同。 請注意髓堪,%@可以是謂詞中描述有效的任何對象的占位符,例如NSDate娘荡,NSNumber干旁,NSDecimalNumber或NSString的實例。

@"%K == %@"
This predicate checks whether the value of the key %K is the same as the value of the object %@. The variables are supplied at runtime as arguments to predicateWithFormat:.

  • 該謂詞檢查鍵%K的值是否與對象%@的值相同炮沐。 變量在運行時作為predicateWithFormat的參數(shù)提供争群。

@"name IN $NAME_LIST"
This is a template for a predicate that checks whether the value of the key name is in the variable $NAME_LIST (no quotes) that is supplied at runtime using predicateWithSubstitutionVariables:.

  • 這是謂詞的模板,用于檢查鍵名的值是否在運行時使用predicateWithSubstitutionVariables:提供的變量$ NAME_LIST(無引號)中大年。

@"'name' IN $NAME_LIST"
This is a template for a predicate that checks whether the constant value 'name' (note the quotes around the string) is in the variable $NAME_LIST that is supplied at runtime using predicateWithSubstitutionVariables:.

  • 這是一個謂詞模板换薄,用于檢查常量值'name'(注意字符串周圍的引號)是否在運行時使用predicateWithSubstitutionVariables:提供的變量$ NAME_LIST中。

@"$name IN $NAME_LIST"
This is a template for a predicate that expects values to be substituted (using predicateWithSubstitutionVariables:) for both $NAME and $NAME_LIST.

  • 這是一個謂詞模板翔试,它希望為NAME和 NAME_LIST替換值(使用predicateWithSubstitutionVariables :)轻要。

@"%K == '%@'"
This predicate checks whether the value of the key %K is equal to the string literal “%@“ (note the single quotes around %@). The key name %K is supplied at runtime as an argument to predicateWithFormat:.

  • 該謂詞檢查鍵%K的值是否等于字符串文字“%@”(注意%@周圍的單引號)。 密鑰名稱%K在運行時作為predicateWithFormat:的參數(shù)提供垦缅。
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末冲泥,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌凡恍,老刑警劉巖志秃,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異嚼酝,居然都是意外死亡浮还,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進店門闽巩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來碑定,“玉大人,你說我怎么就攤上這事又官⊙恿酰” “怎么了?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵六敬,是天一觀的道長碘赖。 經(jīng)常有香客問我,道長外构,這世上最難降的妖魔是什么普泡? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮审编,結果婚禮上撼班,老公的妹妹穿的比我還像新娘。我一直安慰自己垒酬,他們只是感情好砰嘁,可當我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著勘究,像睡著了一般矮湘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上口糕,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天缅阳,我揣著相機與錄音,去河邊找鬼景描。 笑死十办,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的超棺。 我是一名探鬼主播向族,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼说搅!你這毒婦竟也來了炸枣?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎适肠,沒想到半個月后霍衫,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡侯养,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年敦跌,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片逛揩。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡柠傍,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出辩稽,到底是詐尸還是另有隱情惧笛,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布逞泄,位于F島的核電站患整,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏喷众。R本人自食惡果不足惜各谚,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望到千。 院中可真熱鬧昌渤,春花似錦、人聲如沸憔四。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽加矛。三九已至履婉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間斟览,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工辑奈, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留苛茂,地道東北人。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓鸠窗,卻偏偏與公主長得像妓羊,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子稍计,可洞房花燭夜當晚...
    茶點故事閱讀 44,976評論 2 355