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類(lèi)方法直接從字符串創(chuàng)建謂詞。 您可以將謂詞定義為字符串,也可以使用變量替換。 在運(yùn)行時(shí),執(zhí)行變量替換(如果有),并解析生成的字符串以創(chuàng)建相應(yīng)的謂詞和表達(dá)式對(duì)象。 以下示例使用兩個(gè)比較謂詞創(chuàng)建復(fù)合謂詞。
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]是一個(gè)不區(qū)分大小寫(xiě)且對(duì)變音不敏感的修改后的“l(fā)ike”運(yùn)算符。)有關(guān)字符串語(yǔ)法的完整說(shuō)明以及所有可用運(yùn)算符的列表,請(qǐng)參閱謂詞格式字符串語(yǔ)法。

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.

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

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í)行任何語(yǔ)義類(lèi)型檢查。 它可以最大限度地嘗試創(chuàng)建合適的表達(dá)式,但是 - 特別是在替換變量的情況下 - 可能會(huì)生成運(yùn)行時(shí)錯(cuò)誤。

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.

  • 這種方法通常最適用于預(yù)定義的查詢(xún)術(shù)語(yǔ),盡管變量替換允許相當(dāng)大的靈活性。 這種技術(shù)的缺點(diǎn)是你必須注意避免在字符串中引入錯(cuò)誤 - 在運(yùn)行之前你不會(huì)發(fā)現(xiàn)錯(cuò)誤。

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.

  • 字符串常量必須在表達(dá)式中引用 - 單引號(hào)和雙引號(hào)都是可接受的,但必須適當(dāng)配對(duì)(即雙引號(hào)(“)與單引號(hào)(')不匹配。)如果使用變量替換請(qǐng)使用%@(例如firstName,如%@),引號(hào)會(huì)自動(dòng)添加。如果在格式字符串中使用字符串常量,則必須自己引用它們,如下例所示。
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.

  • 使用通配符時(shí)必須考慮自動(dòng)引用 - 必須在替換之前將通配符添加到變量,如以下示例所示。
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”,謂詞評(píng)估產(chǎn)生運(yùn)行時(shí)錯(cuò)誤:
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] %@*").

  • 最后,以下片段導(dǎo)致運(yùn)行時(shí)解析錯(cuò)誤(無(wú)法解析格式字符串“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.

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

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

  • 有關(guān)變量表達(dá)式的更多信息,請(qǐng)參閱使用謂詞模板創(chuàng)建謂詞。

Boolean Values

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

  • 您可以指定并測(cè)試布爾值的相等性,如以下示例所示:
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.

  • 因?yàn)樽址兞吭谑褂茫替換為格式字符串時(shí)會(huì)被引號(hào)括起來(lái),所以不能使用%@來(lái)指定動(dòng)態(tài)屬性名稱(chēng) - 如以下示例所示。
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".

  • 在這種情況下,謂詞格式字符串的計(jì)算結(jié)果為“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.

  • 如果要指定動(dòng)態(tài)屬性名稱(chēng),請(qǐng)?jiān)诟袷阶址惺褂茫,如以下片段所示。
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).

  • 在這種情況下,謂詞格式字符串的計(jì)算結(jié)果為firstName,like “Adam”(請(qǐng)注意firstName周?chē)鷽](méi)有引號(hào))。

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)建謂詞和表達(dá)式實(shí)例。 NSComparisonPredicate和NSCompoundPredicate提供了方便的方法,使您可以分別輕松創(chuàng)建復(fù)合謂詞和比較謂詞。 NSComparisonPredicate提供了許多運(yùn)算符,從簡(jiǎn)單的相等性測(cè)試到自定義函數(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)。 請(qǐng)注意,兩個(gè)比較謂詞都使用相同的左側(cè)表達(dá)式。
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.

  • 這種技術(shù)的缺點(diǎn)應(yīng)該是顯而易見(jiàn)的 - 您可能需要編寫(xiě)大量代碼。 優(yōu)點(diǎn)是它不易于拼寫(xiě)和其他印刷錯(cuò)誤,這些錯(cuò)誤只能在運(yùn)行時(shí)發(fā)現(xiàn),而且可能比依賴(lài)字符串解析更快。

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

  • 當(dāng)謂詞的創(chuàng)建本身是動(dòng)態(tài)的時(shí),這種技術(shù)最有用,例如在謂詞構(gòu)建器中。

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.

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

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

  • 這相當(dāng)于直接創(chuàng)建變量表達(dá)式,如以下示例所示。
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.)

  • 要?jiǎng)?chuàng)建有效的謂詞來(lái)評(píng)估對(duì)象,可以使用NSPredicate方法predicateWithSubstitutionVariables:傳入包含要替換的變量的字典。 (請(qǐng)注意,字典必須包含謂詞中指定的所有變量的鍵值對(duì)。)
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.

  • 因?yàn)樘鎿Q字典必須包含謂詞中指定的所有變量的鍵值對(duì),所以如果要匹配空值,則必須在字典中提供空值,如以下示例所示。
NSPredicate *predicate = [NSPredicate
    predicateWithFormat:@"date = $DATE"];
predicate = [predicate predicateWithSubstitutionVariables:
    [NSDictionary dictionaryWithObject:[NSNull null] forKey:@"DATE"]];

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

  • 這個(gè)例子形成的謂詞是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ū)分格式字符串中的不同類(lèi)型的值很重要。 另請(qǐng)注意,單引號(hào)或雙引號(hào)變量(或替換變量字符串)將導(dǎo)致%@,%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的值是否與在運(yùn)行時(shí)作為predicateWithFormat:的參數(shù)提供的對(duì)象%@的值相同。 請(qǐng)注意,%@可以是謂詞中描述有效的任何對(duì)象的占位符,例如NSDate,NSNumber,NSDecimalNumber或NSString的實(shí)例。

@"%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的值是否與對(duì)象%@的值相同。 變量在運(yùn)行時(shí)作為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:.

  • 這是謂詞的模板,用于檢查鍵名的值是否在運(yùn)行時(shí)使用predicateWithSubstitutionVariables:提供的變量$ NAME_LIST(無(wú)引號(hào))中。

@"'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:.

  • 這是一個(gè)謂詞模板,用于檢查常量值'name'(注意字符串周?chē)囊?hào))是否在運(yùn)行時(shí)使用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.

  • 這是一個(gè)謂詞模板,它希望為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的值是否等于字符串文字“%@”(注意%@周?chē)膯我?hào))。 密鑰名稱(chēng)%K在運(yùn)行時(shí)作為predicateWithFormat:的參數(shù)提供。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容