Cocoa provides three predicate classes: NSPredicate, and two subclasses of NSPredicate, NSComparisonPredicate andNSCompoundPredicate.
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.
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".
If you want to specify a dynamic property name, you use %K in the format string, as shown in the following fragment.
predicate = [NSPredicate predicateWithFormat:@"%K like %@", |
attributeName, attributeValue]; |
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. NSComparisonPredicateprovides a number of operators ranging from simple equality tests to custom functions.
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.
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.
This technique is most likely to be useful when the creation of the predicate is itself dynamic, such as in a predicate builder.
Creating Predicates Using Predicate Templates
NSPredicate *predicateTemplate = [NSPredicate |
predicateWithFormat:@"lastName like[c] $LAST_NAME"]; |
This is equivalent to creating the variable expression directly as shown in the following example.
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 methodpredicateWithSubstitutionVariables: 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.)
NSPredicate *predicate = [predicateTemplate predicateWithSubstitutionVariables: |
[NSDictionary dictionaryWithObject:@"Turner" forKey:@"LAST_NAME"]]; |
The new predicate returned by this example is 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>.
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.
-
This predicate checks whether the value of the key
attributeNameis the same as the value of the object%@that is supplied at runtime as an argument topredicateWithFormat:. Note that%@can be a placeholder for any object whose description is valid in the predicate, such as an instance ofNSDate,NSNumber,NSDecimalNumber, orNSString. -
This predicate checks whether the value of the key
%Kis the same as the value of the object%@. The variables are supplied at runtime as arguments topredicateWithFormat:. -
This is a template for a predicate that checks whether the value of the key
nameis in the variable$NAME_LIST(no quotes) that is supplied at runtime usingpredicateWithSubstitutionVariables:. -
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_LISTthat is supplied at runtime usingpredicateWithSubstitutionVariables:. -
This is a template for a predicate that expects values to be substituted (using
predicateWithSubstitutionVariables:) for both$NAMEand$NAME_LIST. -
This predicate checks whether the value of the key
%Kis equal to the string literal “%@“ (note the single quotes around%@). The key name%Kis supplied at runtime as an argument topredicateWithFormat:.
@"attributeName == %@"
@"%K == %@"
@"name IN $NAME_LIST"
@"'name' IN $NAME_LIST"
@"$name IN $NAME_LIST"
@"%K == '%@'"
本文深入探讨了Objective-C与Swift两种编程语言在iOS开发领域的应用与区别,详细介绍了它们的特点、优势及如何在实际项目中选择合适的语言进行开发。

1261

被折叠的 条评论
为什么被折叠?



