iOS开发-NSPredicate谓词专题


Cocoa提供了一个名为NSPredicate的类,它用于指定过滤器的条件。可以创建NSPredicate对象,通过它准确的描述所需的条件,通过谓词筛选每个对象,判断它们是否与条件相匹配。Cocoa用NSPredicate描述查询的方式,原理类似于在数据库中进行查询,可以在数据库风格的API中使用NSPredicate类,比如Core DataSpotlight

代码示例:

两个对象类:Student和Teacher

//
//  Student.h
//  谓词
//
//  Created by on 15/3/16.
//  Copyright (c) 2015年 apple. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Student : NSObject

@property (nonatomic, retain) NSString *stuName;
@property (nonatomic, assign) NSInteger stuAge;

- (id)initWithName:(NSString *)name andAge:(NSInteger)age;

@end
//
//  Student.m
//  谓词
//
//  Created by on 15/3/16.
//  Copyright (c) 2015年 apple. All rights reserved.
//

#import "Student.h"

@implementation Student

- (id)initWithName:(NSString *)name andAge:(NSInteger)age {
    if (self = [super init]) {
        _stuName = name;
        _stuAge = age;
    }
    return self;
}

@end
//
//  Teacher.h
//  谓词
//
//  Created by on 15/3/16.
//  Copyright (c) 2015年 apple. All rights reserved.
//

#import <Foundation/Foundation.h>

@class Student;

@interface Teacher : NSObject

@property (nonatomic, strong) Student *student;
@property (nonatomic, retain) NSString *teaName;
@property (nonatomic, assign) NSInteger teaAge;

- (id)initWithName:(NSString *)name andAge:(NSInteger)age;

@end
//
//  Teacher.m
//  谓词
//
//  Created by wujiafeng on 15/3/16.
//  Copyright (c) 2015年 apple. All rights reserved.
//

#import "Teacher.h"

@implementation Teacher

- (id)initWithName:(NSString *)name andAge:(NSInteger)age {
    if (self = [super init]) {
        _teaName = name;
        _teaAge = age;
    }
    return self;
}

@end

测试:

//
//  main.m
//  谓词
//
//  Created by wujiafeng on 15/3/16.
//  Copyright (c) 2015年 apple. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Student.h"
#import "Teacher.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Student *stu = [[Student alloc] initWithName:@"Jack" andAge:12];
        Teacher *teacher = [[Teacher alloc] initWithName:@"Tom" andAge:20];
        
//        设置teacher中的student对象
        teacher.student = stu;
        
//        创建谓词
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"student._stuName == 'Jack'"];
//        通知接收对象(即谓词)根据指定的对象计算自身的值
        BOOL match = [predicate evaluateWithObject:teacher];
        NSLog(@"%s", (match) ? "YES" : "NO");
        
        
        NSMutableArray *stuArray = [NSMutableArray arrayWithCapacity:10];
        for (int i = 0; i < 10; i++) {
            Student *studentTemp = [[Student alloc] initWithName:[NSString stringWithFormat:@"jack%d", i] andAge:20 + i];
            [stuArray addObject:studentTemp];
        }
        
        NSPredicate *pre = [NSPredicate predicateWithFormat:@"_stuAge > 25"];
//        迭代出年龄大于25岁的学生信息
        for (Student *temp in stuArray) {
            if ([pre evaluateWithObject:temp]) {
                NSLog(@"姓名:%@,年龄:%ld", temp.stuName, temp.stuAge);
            }
        }
        
//        调用数组过滤器实现过滤
//        此方法会返回一个NSArray数组
        NSArray *stus = [stuArray filteredArrayUsingPredicate:pre];
        
//        此方法是直接从NSMutableArray中过滤掉不满足条件的项
        [stuArray filterUsingPredicate:pre];
//        KVC的运用
        NSArray *stuNamesForMutable = [stuArray valueForKey:@"stuName"];
        NSLog(@"%@", stuNamesForMutable);
        
        NSLog(@"=======调用数组方法处理=======");
        for (Student *temp in stus) {
            NSLog(@"姓名:%@,年龄:%ld", temp.stuName, temp.stuAge);
        }
        
//        KVC的运用
        NSArray *arryForStuName = [stus valueForKey:@"stuName"];
        NSLog(@"%@", arryForStuName);
        
        pre = [NSPredicate predicateWithFormat:@"_stuName == %@", @"Tom"];
//        这里的%K指的是键路径
        pre = [NSPredicate predicateWithFormat:@"%K == %@", @"_stuName", @"Tom"];
        
        
//        另一种方式是将变量名放入字符串中,类似于环境变量
        NSPredicate *predicateTemplate = [NSPredicate predicateWithFormat:@"_stuName == $NAME"];
//        这里键是变量名(不包括美元符号),这里用字符串Jack作为键“NAME”的值
        NSDictionary *varDic = [NSDictionary dictionaryWithObjectsAndKeys:@"Jack", @"NAME", nil];
        pre = [predicateTemplate predicateWithSubstitutionVariables:varDic];
        BOOL match1 = [pre evaluateWithObject:stu];
        NSLog(@"%s", (match1) ? "YES" : "NO");
    }
    return 0;
}

输出结果如下:

2015-03-16 18:30:23.938 谓词[581:15147] YES

2015-03-16 18:30:23.939 谓词[581:15147] 姓名:jack6,年龄:26

2015-03-16 18:30:23.939 谓词[581:15147] 姓名:jack7,年龄:27

2015-03-16 18:30:23.939 谓词[581:15147] 姓名:jack8,年龄:28

2015-03-16 18:30:23.939 谓词[581:15147] 姓名:jack9,年龄:29

2015-03-16 18:30:23.939 谓词[581:15147] (
jack6,
jack7,
jack8,
jack9
)

2015-03-16 18:30:23.939 谓词[581:15147] =======调用数组方法处理=======

2015-03-16 18:30:23.939 谓词[581:15147] 姓名:jack6,年龄:26

2015-03-16 18:30:23.940 谓词[581:15147] 姓名:jack7,年龄:27

2015-03-16 18:30:23.940 谓词[581:15147] 姓名:jack8,年龄:28

2015-03-16 18:30:23.940 谓词[581:15147] 姓名:jack9,年龄:29

2015-03-16 18:30:23.940 谓词[581:15147] (
jack6,
jack7,
jack8,
jack9
)
2015-03-16 18:30:23.940 谓词[581:15147] YES

推荐阅读更多精彩内容