本文共 6586 字,大约阅读时间需要 21 分钟。
Cocoa中谓词(Predicate)提供了一个通用的查询方式处理数据,可以获取和指定数据的过滤形式,Cocoa实际开发中可以是使用NSPredicate及其父类NSComparisonPredicate和NSCompoundPredicate.其风格类似于SQL查询语言和正则表达式的混合体,提供了具有表现力的,自然语言界面来定义一个集合被搜寻的逻辑条件。一般来说稍微操作过数据库基本上很容易理解其中的方法,至于使用的方法也很简单。
首先来一段比较简单的代码:
1 2 3 4 | NSPredicate *predicate = [ NSPredicate predicateWithFormat:@ "SELF IN %@" , @[@ "keso" , @ "FlyElephant" , @ "博客园" ]]; if ([predicate evaluateWithObject:@ "keso" ]) { NSLog (@ "keso" ); }; |
第一行代码初始化一个查询条件,第二句就是判断数据在不在结果集中,跟SQL基本上一样,通过IN就能大概了解其功能,SELF表示本身,非常常用。
接下来可以类似于SQL中like语句的代码:
1 2 3 4 5 6 | NSArray *array = [[ NSArray alloc]initWithObjects:@ "北京" ,@ "上海" ,@ "广州" ,@ "深圳" , nil ]; NSPredicate *preBegin= [ NSPredicate predicateWithFormat:@ "SELF beginswith[c] %@" ,@ "北" ]; NSPredicate *preContain= [ NSPredicate predicateWithFormat:@ "SELF contains[c] %@" ,@ "海" ]; NSLog (@ "%@" ,[array filteredArrayUsingPredicate:preBegin][0]); NSLog (@ "%@" ,[array filteredArrayUsingPredicate:preContain][0]); |
第一次就是先初始化数组,然后创建条件,通过filteredArrayUsingPredicate过滤数组;
NSDictionary可以用谓词来过滤它的键和值(两者都为NSArray对象);
NSOrderedSet可以由过滤的NSArray或NSSet生成一个新的有序的集,或者NSMutableSet可以简单的removeObjectsInArray来传递通过否定predicate过滤的对象。
NSPredicate
谓词的在Core Data同样适用,在管理对象环境中,谓词由持久化存储助理(persistent store coordinator)评估,而集合则是内存中过滤。这时候我们有必要里了解一下基本比较运算符:
1 2 3 4 5 6 7 8 9 | NSPredicate *betweenPredicate = [ NSPredicate predicateWithFormat: @ "attributeName BETWEEN %@" , @[ @1 , @10 ]]; NSDictionary *dictionary = @{ @ "attributeName" : @5 }; BOOL between = [betweenPredicate evaluateWithObject:dictionary]; if (between) { NSLog (@ "比较运算符between" ); } |
1 2 3 4 5 6 | NSString *regex = @ "[A-Za-z]+" ; NSPredicate *matchpredicate = [ NSPredicate predicateWithFormat:@ "SELF MATCHES %@" , regex]; if ([matchpredicate evaluateWithObject:@ "keso" ]) { NSLog (@ "匹配成功" ); } |
1 2 3 4 5 6 7 8 9 10 11 | @interface People : NSObject @property (strong, nonatomic ) NSString *FirstName; @property (strong, nonatomic ) NSString *LastName; @property ( nonatomic ) NSInteger Height; - ( NSString *)description; @end |
People.m文件:
1 2 3 4 5 6 7 | @implementation People - ( NSString *)description { return [ NSString stringWithFormat:@ "%@%@" , self .LastName, self .FirstName]; }; @end |
具体实现代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | NSArray *firstNames =[[ NSArray alloc]initWithObjects:@ "泽东" , @ "恩来" , @ "介石" , @ "中山" , nil ]; NSArray *lastNames = @[ @ "毛" , @ "周" , @ "蒋" , @ "孙" ]; NSArray *familiar = @[ @100 , @99 , @99 , @98 ]; NSMutableArray *dataList= [ NSMutableArray array]; [firstNames enumerateObjectsUsingBlock:^( id obj, NSUInteger idx, BOOL *stop) { People *people= [[People alloc] init]; people.FirstName = firstNames[idx]; people.LastName = lastNames[idx]; people.Height= [familiar[idx] integerValue]; [dataList addObject:people]; }]; NSPredicate *firstPredicate = [ NSPredicate predicateWithFormat:@ "FirstName = '恩来'" ]; NSPredicate *lastPredicate = [ NSPredicate predicateWithFormat:@ "LastName = %@" , @ "蒋" ]; NSPredicate *heightPredicate = [ NSPredicate predicateWithFormat:@ "Height < 99" ]; //名搜索 NSLog (@ "名: %@" ,[dataList filteredArrayUsingPredicate:firstPredicate][0]); //姓搜索 NSLog (@ "姓: %@" , [dataList filteredArrayUsingPredicate:lastPredicate][0]); //知名度 NSLog (@ "知名度: %@" , [dataList filteredArrayUsingPredicate:heightPredicate][0]); |
其实开始讲的NSCompoundPredicate和
NSComparisonPredicate,因为有关系操作,基本上类似,如果通过混合搜索可以使用and,or实现,比如一下代码是等价的:
1 2 3 | NSCompoundPredicate *comPredicate=[ NSCompoundPredicate andPredicateWithSubpredicates:@[[ NSPredicate predicateWithFormat:@ "Height > 90" ], [ NSPredicate predicateWithFormat:@ "FirstName = %@" , @ "介石" ]]]; NSPredicate *secondPredicate=[ NSPredicate predicateWithFormat:@ "(Height > 90) AND (FirstName = %@)" , @ "介石" ]; |
NSComparisonPredicate有两个调用的静态方法:
1 2 | + ( NSComparisonPredicate *)predicateWithLeftExpression:( NSExpression *)lhs rightExpression:( NSExpression *)rhs modifier:( NSComparisonPredicateModifier )modifier type:( NSPredicateOperatorType )type options:( NSComparisonPredicateOptions )options; + ( NSComparisonPredicate *)predicateWithLeftExpression:( NSExpression *)lhs rightExpression:( NSExpression *)rhs customSelector:( SEL )selector; |
其实就是一个表达式的拼接的过程,不过具体的实现苹果给封装好了,一下是NSPredicateOperatorType类型:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | typedef NS_ENUM ( NSUInteger , NSPredicateOperatorType ) { NSLessThanPredicateOperatorType = 0, // compare: returns NSOrderedAscending NSLessThanOrEqualToPredicateOperatorType , // compare: returns NSOrderedAscending || NSOrderedSame NSGreaterThanPredicateOperatorType , // compare: returns NSOrderedDescending NSGreaterThanOrEqualToPredicateOperatorType , // compare: returns NSOrderedDescending || NSOrderedSame NSEqualToPredicateOperatorType , // isEqual: returns true NSNotEqualToPredicateOperatorType , // isEqual: returns false NSMatchesPredicateOperatorType , NSLikePredicateOperatorType , NSBeginsWithPredicateOperatorType , NSEndsWithPredicateOperatorType , NSInPredicateOperatorType , // rhs contains lhs returns true NSCustomSelectorPredicateOperatorType , NSContainsPredicateOperatorType NS_ENUM_AVAILABLE (10_5, 3_0) = 99, // lhs contains rhs returns true NSBetweenPredicateOperatorType NS_ENUM_AVAILABLE (10_5, 3_0) }; |
本文转自Fly_Elephant博客园博客,原文链接:http://www.cnblogs.com/xiaofeixiang/p/4264869.html,如需转载请自行联系原作者