iOS开发-NSPredicate

简介:

Cocoa中谓词(Predicate)提供了一个通用的查询方式处理数据,可以获取和指定数据的过滤形式,Cocoa实际开发中可以是使用NSPredicate及其父类NSComparisonPredicate和NSCompoundPredicate.其风格类似于SQL查询语言和正则表达式的混合体,提供了具有表现力的,自然语言界面来定义一个集合被搜寻的逻辑条件。一般来说稍微操作过数据库基本上很容易理解其中的方法,至于使用的方法也很简单。

集合中的NSPredicate

Foundation提供使用谓词(predicate)来过滤NSArray/NSMutableArray&NSSet/NSMutableSet的方法。
不可变的集合,NSArray&NSSet,可以通过评估接收到的predicate来返回一个不可变集合的方法filteredArrayUsingPredicate和filteredSetUsingPredicate;
可变集合,NSMutableArray&NSMutableSet,可以使用方法filterUsingPredicate:可以通过运行接收到的谓词来移除评估结果为FALSE的对象。

首先来一段比较简单的代码: 

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过滤的对象。

Core Data中的NSPredicate

谓词的在Core Data同样适用,在管理对象环境中,谓词由持久化存储助理(persistent store coordinator)评估,而集合则是内存中过滤。这时候我们有必要里了解一下基本比较运算符:

  • =, ==:左边的表达式和右边的表达式相等。
  • >=, =>:左边的表达式大于或者等于右边的表达式。
  • <=, =<:左边的表达式小于等于右边的表达式。
  • >:左边的表达式大于右边的表达式。
  • <:左边的表达式小于右边的表达式。
  • !=, <>:左边的表达式不等于右边的表达式。
BETWEEN:左边的表达式等于右边的表达式的值或者介于它们之间。右边是一个有两个指定上限和下限的数值的数列(指定顺序的数列)。比如,1 BETWEEN { 0 , 33 },或者INPUT BETWEEN {INPUT BETWEEN {LOWER, $UPPER }。可参考以下代码:
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" );
    } 
基本复合谓词
  • AND, &&:逻辑与.
  • OR, ||:逻辑或.
  • NOT, !:逻辑非
字符串比较
字符串比较非常常用,以下的都应该比较熟悉:
  • BEGINSWITH[cd] $FIRST_NAME。
  • BEGINSWITH:左边的表达式以右边的表达式作为开始。
  • CONTAINS:左边的表达式包含右边的表达式。
  • ENDSWITH:左边的表达式以右边的表达式作为结束。
  • LIKE:左边的表达式等于右边的表达式:?和*可作为通配符,其中?匹配1个字符,*匹配0个或者多个字符。
  • MATCHES:左边的表达式根据ICU v3的regex风格比较,等于右边的表达式。
可参考以下代码:
1
2
3
4
5
6
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:结果始终为假的谓词。
下面提供一个简单使用谓词搜索类对象的代码:
新建一个People类,头文件:
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,如需转载请自行联系原作者

相关文章
|
1月前
|
iOS开发 开发者
uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
141 67
uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
|
3月前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。
|
2天前
|
JavaScript 搜索推荐 Android开发
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
21 8
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
|
2月前
|
iOS开发 开发者 MacOS
深入探索iOS开发中的SwiftUI框架
【10月更文挑战第21天】 本文将带领读者深入了解Apple最新推出的SwiftUI框架,这一革命性的用户界面构建工具为iOS开发者提供了一种声明式、高效且直观的方式来创建复杂的用户界面。通过分析SwiftUI的核心概念、主要特性以及在实际项目中的应用示例,我们将展示如何利用SwiftUI简化UI代码,提高开发效率,并保持应用程序的高性能和响应性。无论你是iOS开发的新手还是有经验的开发者,本文都将为你提供宝贵的见解和实用的指导。
143 66
|
2月前
|
存储 监控 API
app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
87 11
|
2月前
|
开发框架 Android开发 iOS开发
安卓与iOS开发中的跨平台策略:一次编码,多平台部署
在移动应用开发的广阔天地中,安卓和iOS两大阵营各占一方。随着技术的发展,跨平台开发框架应运而生,它们承诺着“一次编码,到处运行”的便捷。本文将深入探讨跨平台开发的现状、挑战以及未来趋势,同时通过代码示例揭示跨平台工具的实际运用。
173 3
|
2月前
|
Java 调度 Android开发
安卓与iOS开发中的线程管理差异解析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自拥有独特的魅力。如同东西方文化的差异,它们在处理多线程任务时也展现出不同的哲学。本文将带你穿梭于这两个平台之间,比较它们在线程管理上的核心理念、实现方式及性能考量,助你成为跨平台的编程高手。
|
3月前
|
存储 前端开发 Swift
探索iOS开发:从新手到专家的旅程
本文将带您领略iOS开发的奇妙之旅,从基础概念的理解到高级技巧的掌握,逐步深入iOS的世界。文章不仅分享技术知识,还鼓励读者在编程之路上保持好奇心和创新精神,实现个人成长与技术突破。
|
3月前
|
安全 IDE Swift
探索iOS开发之旅:从初学者到专家
在这篇文章中,我们将一起踏上iOS开发的旅程,从基础概念的理解到深入掌握核心技术。无论你是编程新手还是希望提升技能的开发者,这里都有你需要的指南和启示。我们将通过实际案例和代码示例,展示如何构建一个功能齐全的iOS应用。准备好了吗?让我们一起开始吧!
|
3月前
|
安全 Swift iOS开发
Swift 与 UIKit 在 iOS 应用界面开发中的关键技术和实践方法
本文深入探讨了 Swift 与 UIKit 在 iOS 应用界面开发中的关键技术和实践方法。Swift 以其简洁、高效和类型安全的特点,结合 UIKit 丰富的组件和功能,为开发者提供了强大的工具。文章从 Swift 的语法优势、类型安全、编程模型以及与 UIKit 的集成,到 UIKit 的主要组件和功能,再到构建界面的实践技巧和实际案例分析,全面介绍了如何利用这些技术创建高质量的用户界面。
70 2

热门文章

最新文章

  • 1
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    23
  • 2
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
    21
  • 3
    uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
    141
  • 4
    【05】2025年1月首发完整版-篇幅较长-苹果app如何上架到app store完整流程·不借助第三方上架工具的情况下无需花钱但需仔细学习-优雅草央千澈详解关于APP签名以及分发-们最关心的一篇来了-IOS上架app
    223
  • 5
    app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
    87
  • 6
    深入探索iOS开发中的SwiftUI框架
    143
  • 7
    ios样式开关按钮jQuery插件
    58
  • 8
    Android与iOS生态差异深度剖析:技术架构、开发体验与市场影响####
    74
  • 9
    深入探索iOS与Android操作系统的安全性差异
    102
  • 10
    安卓与iOS开发中的跨平台策略:一次编码,多平台部署
    174