首先申明下,本文为笔者学习《Objective-C 基础教程》的笔记,并加入笔者自己的理解和归纳总结。
NSPredicate
类,指定过滤器的条件,筛选每个对象,判断它们是否与条件相匹配。
1. 创建谓词
predicateWithFormat:
创建一个谓词。
+ (id)predicateWithFormat:(NSString *)format...;
evaluateWithObject:
接受对象,根据指定的对象计算自身的值。
- (BOOL)evaluateWithObject:(id)value;
filteredArrayUsingPredicate:
是NSArray
数组中的一种类别方法,它将过滤数组内容
@interface ShapeBounds : NSObject {
int width;
int height;
}
@property int width;
@property int height;
@end
@implementation ShapeBounds
@synthesize width;
@synthesize height;
- (NSString *)description {
return [NSString stringWithFormat:@"(%d, %d)", width, height];
}
@end
@interface Shape : NSObject {
ShapeBounds *bounds;
}
@property (readwrite, retain) ShapeBounds *bounds;
@end
@implementation Shape
@synthesize bounds;
- (id)init {
if (self = [super init]) {
bounds = [[ShapeBounds alloc] init];
}
return self;
}
- (NSString *)description {
return [NSString stringWithFormat:@"Shape bounds = %@", bounds];
}
@end
Shape * createShape(int width, int height) {
Shape *shape = [[Shape alloc] init];
shape.bounds.width = width;
shape.bounds.height = height;
return shape;
}
int main(int argc, const char* argv[]) {
@autoreleasepool {
ShapeBounds *bounds = [[ShapeBounds alloc] init];
bounds.width = 20;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"width == 20"];
if ([predicate evaluateWithObject:bounds]) {
NSLog(@"evaluateWithObject true");
}
predicate = [NSPredicate predicateWithFormat:@"bounds.width == 20"];
NSMutableArray *array = [NSMutableArray arrayWithCapacity:4];
[array addObject:createShape(20, 30)];
[array addObject:createShape(40, 50)];
[array addObject:createShape(20, 45)];
NSArray *result = [array filteredArrayUsingPredicate:predicate];
NSLog(@"%@", result);
}
return 0;
}
输出
evaluateWithObject true
(
"Shape bounds = (20, 30)",
"Shape bounds = (20, 45)"
)
2. 格式说明符
可以在谓词字符串中用格式说明符。
predicate = [NSPredicate predicateWithFormat:@"width == %d", 20];
%K
指定关键路径
predicate = [NSPredicate predicateWithFormat:@"%K == %d", @"width", 20];
$
符号用来指定变量,在NSDictionary
中添加数据,使用predicateWithSubstitutionVariables:
构造新的谓词。
predicateTemplate = [NSPredicate predicateWithFormat:@"width == $WIDTH"];
predicate = [predicateTemplate predicateWithSubstitutionVariables:dict];
示例
int main(int argc, const char* argv[]) {
@autoreleasepool {
ShapeBounds *bounds = [[ShapeBounds alloc] init];
bounds.width = 20;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"width == %d", 20];
if ([predicate evaluateWithObject:bounds]) {
NSLog(@"evaluateWithObject true");
}
NSPredicate *predicate1 = [NSPredicate predicateWithFormat:
@"%K == %d", @"width", 20];
if ([predicate1 evaluateWithObject:bounds]) {
NSLog(@"evaluateWithObject true");
}
NSPredicate *predicateTemplate = [NSPredicate predicateWithFormat:
@"width == $WIDTH"];
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:20], @"WIDTH", nil];
NSPredicate *predicate2 = [predicateTemplate
predicateWithSubstitutionVariables:dict];
if ([predicate2 evaluateWithObject:bounds]) {
NSLog(@"evaluateWithObject true");
}
}
return 0;
}
输出
evaluateWithObject true
evaluateWithObject true
evaluateWithObject true
3. 运算符
谓语字符串支持比较运算符(>,>=,<,<=和!=)和逻辑运算符(AND、OR和NOT)。
int main(int argc, const char* argv[]) {
@autoreleasepool {
ShapeBounds *bounds = [[ShapeBounds alloc] init];
bounds.width = 20;
bounds.height = 30;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"width > 10"];
if ([predicate evaluateWithObject:bounds]) {
NSLog(@"evaluateWithObject >");
}
predicate = [NSPredicate predicateWithFormat:@"width < 30"];
if ([predicate evaluateWithObject:bounds]) {
NSLog(@"evaluateWithObject <");
}
predicate = [NSPredicate predicateWithFormat:@"width != 30"];
if ([predicate evaluateWithObject:bounds]) {
NSLog(@"evaluateWithObject !=");
}
predicate = [NSPredicate predicateWithFormat:
@"(width == 20) AND (height == 30)"];
if ([predicate evaluateWithObject:bounds]) {
NSLog(@"evaluateWithObject AND");
}
predicate = [NSPredicate predicateWithFormat:@"width BETWEEN {10, 30}"];
if ([predicate evaluateWithObject:bounds]) {
NSLog(@"evaluateWithObject BETWEEN");
}
predicate = [NSPredicate predicateWithFormat:@"width IN {10, 20, 30}"];
if ([predicate evaluateWithObject:bounds]) {
NSLog(@"evaluateWithObject IN");
}
// SELF是响应谓词计算的对象
predicate = [NSPredicate predicateWithFormat:@"SELF.width IN {10, 20, 30}"];
if ([predicate evaluateWithObject:bounds]) {
NSLog(@"evaluateWithObject IN");
}
predicate = [NSPredicate predicateWithFormat:@"SELF IN {'Tom', 'Mike'}"];
NSArray *array = [NSArray arrayWithObjects:@"Tom", @"July", nil];
NSArray *result = [array filteredArrayUsingPredicate:predicate];
NSLog(@"%@", result);
}
return 0;
}
输出
evaluateWithObject >
evaluateWithObject <
evaluateWithObject !=
evaluateWithObject AND
evaluateWithObject BETWEEN
evaluateWithObject IN
evaluateWithObject IN
(
Tom
)