iOS开发-NSPredicate
Cocoa中谓词(Predicate)提供了一个通用的查询方式处理数据,可以获取和指定数据的过滤形式,Cocoa实际开发中可以是使用NSPredicate及其父类NSComparisonPredicate和NSCompoundPredicate.其风格类似于SQL查询语言和正则表达式的混合体,提供了具有表现力的,自然语言界面来定义一个集合被搜寻的逻辑条件。一般来说稍微操作过数据库基本上很容易理解其中的方法,至于使用的方法也很简单。
集合中的NSPredicate
首先来一段比较简单的代码:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF IN %@", @[@"keso", @"FlyElephant", @"博客园"]];
if ([predicate evaluateWithObject:@"keso"]) {
NSLog(@"keso");
};
第一行代码初始化一个查询条件,第二句就是判断数据在不在结果集中,跟SQL基本上一样,通过IN就能大概了解其功能,SELF表示本身,非常常用。
接下来可以类似于SQL中like语句的代码:
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过滤的对象。
Core Data中的NSPredicate
谓词的在Core Data同样适用,在管理对象环境中,谓词由持久化存储助理(persistent store coordinator)评估,而集合则是内存中过滤。这时候我们有必要里了解一下基本比较运算符:
- =, ==:左边的表达式和右边的表达式相等。
- >=, =>:左边的表达式大于或者等于右边的表达式。
- <=, =<:左边的表达式小于等于右边的表达式。
- >:左边的表达式大于右边的表达式。
- <:左边的表达式小于右边的表达式。
- !=, <>:左边的表达式不等于右边的表达式。
NSPredicate *betweenPredicate =
[NSPredicate predicateWithFormat: @"attributeName BETWEEN %@", @[@1, @10]]; NSDictionary *dictionary = @{ @"attributeName" : @5 }; BOOL between = [betweenPredicate evaluateWithObject:dictionary];
if (between) {
NSLog(@"比较运算符between");
}
- AND, &&:逻辑与.
- OR, ||:逻辑或.
- NOT, !:逻辑非
- BEGINSWITH[cd] $FIRST_NAME。
- BEGINSWITH:左边的表达式以右边的表达式作为开始。
- CONTAINS:左边的表达式包含右边的表达式。
- ENDSWITH:左边的表达式以右边的表达式作为结束。
- LIKE:左边的表达式等于右边的表达式:?和*可作为通配符,其中?匹配1个字符,*匹配0个或者多个字符。
- MATCHES:左边的表达式根据ICU v3的regex风格比较,等于右边的表达式。
NSString *regex = @"[A-Za-z]+";
NSPredicate *matchpredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex]; if ([matchpredicate evaluateWithObject:@"keso"]) {
NSLog(@"匹配成功");
}
- ANY,SOME:指定下列表达式中的任意元素。比如,ANY children.age < 18。
- ALL:指定下列表达式中的所有元素。比如,ALL children.age < 18。
- NONE:指定下列表达式中没有的元素。比如,NONE children.age < 18。它在逻辑上等于NOT (ANY ...)。
- IN:等于SQL的IN操作,左边的表达必须出现在右边指定的集合中。比如,name IN { 'Ben', 'Melissa', 'Nick' }。
- array[index]:指定数组中特定索引处的元素。
- array[FIRST]:指定数组中的第一个元素。
- array[LAST]:指定数组中的最后一个元素。
- array[SIZE]:指定数组的大小。
- TRUEPREDICATE:结果始终为真的谓词。
- FALSEPREDICATE:结果始终为假的谓词。
@interface People : NSObject @property (strong,nonatomic) NSString *FirstName; @property (strong,nonatomic) NSString *LastName; @property (nonatomic) NSInteger Height; - (NSString *)description; @end
People.m文件:
@implementation People - (NSString *)description { return [NSString stringWithFormat:@"%@%@",self.LastName, self.FirstName];
};
@end
具体实现代码:
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实现,比如一下代码是等价的:
NSCompoundPredicate *comPredicate=[NSCompoundPredicate andPredicateWithSubpredicates:@[[NSPredicate predicateWithFormat:@"Height > 90"], [NSPredicate predicateWithFormat:@"FirstName = %@", @"介石"]]]; NSPredicate *secondPredicate=[NSPredicate predicateWithFormat:@"(Height > 90) AND (FirstName = %@)", @"介石"];
NSComparisonPredicate有两个调用的静态方法:
+ (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类型:
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)
};
参考资料:https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Predicates/Articles/pSyntax.html#//apple_ref/doc/uid/TP40001795-SW1
iOS开发-NSPredicate的更多相关文章
- iOS开发系列--数据存取
概览 在iOS开发中数据存储的方式可以归纳为两类:一类是存储为文件,另一类是存储到数据库.例如前面IOS开发系列-Objective-C之Foundation框架的文章中提到归档.plist文件存储, ...
- iOS开发之自定义表情键盘(组件封装与自动布局)
下面的东西是编写自定义的表情键盘,话不多说,开门见山吧!下面主要用到的知识有MVC, iOS开发中的自动布局,自定义组件的封装与使用,Block回调,CoreData的使用.有的小伙伴可能会问写一个自 ...
- iOS开发之表视图爱上CoreData
在接触到CoreData时,感觉就是苹果封装的一个ORM.CoreData负责在Model的实体和sqllite建立关联,数据模型的实体类就相当于Java中的JavaBean, 而CoreData的功 ...
- iOS开发常见BUG和一些小技巧(ps:耐心看完,很实用)
[385][scrollView不接受点击事件,是因为事件传递失败] // // MyScrollView.m // Created by beyond on 15/6/6. // Copyright ...
- iOS开发200个tips总结(一)
tip 1 : 给UIImage添加毛玻璃效果 func blurImage(value:NSNumber) -> UIImage { let context = CIContext(opti ...
- iOS开发中的4种数据持久化方式【二、数据库 SQLite3、Core Data 的运用】
在上文,我们介绍了ios开发中的其中2种数据持久化方式:属性列表.归档解档.本节将继续介绍另外2种iOS持久化数据的方法:数据库 SQLite3.Core Data 的运 ...
- iOS开发——面试指导
iOS面试指导 一 经过本人最近的面试和对面试资料的一些汇总,准备记录这些面试题,以便ios开发工程师找工作复习之用,本人希望有面试经验的同学能和我同时完成这个模块,先出面试题,然后会放出答案. 1. ...
- 【转】iOS 开发怎么入门?
原文网址:http://www.zhihu.com/question/20264108 iOS 开发怎么入门? 请问有设计模式.内存管理方面的资料吗?最好有除了官方文档之外的其它内容,10 条评论 分 ...
- iOS开发tips总结
tip 1 : 给UIImage添加毛玻璃效果 func blurImage(value:NSNumber) -> UIImage { let context = CIContext(opti ...
随机推荐
- [代码审计]XiaoCms(后台任意文件上传至getshell,任意目录删除,会话固定漏洞)
0x00 前言 这段时间就一直在搞代码审计了.针对自己的审计方法做一下总结,记录一下步骤. 审计没他,基础要牢,思路要清晰,姿势要多且正. 下面是自己审计的步骤,正在逐步调整,寻求效率最高. 0x01 ...
- 【基础知识】.Net基础加强第三天
一. 里氏替换原则--类型转换 1. 里氏替换原则:当需要一个父类类型对象的时候,可以给一个子类类型的对象. 2. 里氏替换原则实际也就是发生了隐身转换 3. a.>把子类类型赋值给父类类型, ...
- Swift2.0语言教程之闭包
Swift2.0语言教程之闭包 Swift2.0语言闭包 闭包是自包含的函数代码块,可以在代码中被传递和使用.Swift中的闭包与C和Objective-C中的代码块(blocks)以及其他一些编程语 ...
- DHTML参考手册
中文DHTML参考手册 本dhtml教程由宏博内容管理系统为它的Smarty模板制作者收集的,目的是可以做出更加精美的模板.下面列出了由动态 HTML 定义的对象.DHTML中文参考手册,实用dhtm ...
- 【BZOJ 2721】 2721: [Violet 5]樱花 (筛)
2721: [Violet 5]樱花 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 599 Solved: 354 Description Input ...
- ubuntu16.04服务器apache的ssl证书配置
背景:在腾讯云申请的免费证书1年,服务器ubuntu 16.04版本,我的是多域名 1.ssl模块的安装 sudo a2enmod ssl //开启apache ssl模块 a2ensite defa ...
- BZOJ 2115: [Wc2011] Xor 线性基 dfs
https://www.lydsy.com/JudgeOnline/problem.php?id=2115 每一条从1到n的道路都可以表示为一条从1到n的道路异或若干个环的异或值. 那么把全部的环丢到 ...
- hdoj 5119 Happy Matt Friends 背包DP
Happy Matt Friends Time Limit: 6000/6000 MS (Java/Others) Memory Limit: 510000/510000 K (Java/Others ...
- CGI 、PHP-CGI、FASTCGI、PHP-FPM
CGI是干嘛的? CGI是为了保证web server传递过来的数据是标准格式的,方便CGI程序的编写者.web server(比如说nginx)只是内容的分发者.比如,如果请求的是/index/ht ...
- 用 Apache 发布 ASP.NET 网站
由于服务器需要发布 JSP .PHP.ASP.NET 几种网站进行测试,Apache 肯定是支持 JSP 和 PHP .鉴于 Apache 的开放精神 ,ASP.Net 应该也是支持的,于是乎 Go ...