Objective-C中的NSPredicate
<p>编写软件时,经常需要获取一个对象集合,并通过某些已经条件计算该集合的值。你需要保留符合某个条件的对象,删除那些不满足条件的对象,从而提供一些有意义的对象。</p> <p>在使用软件iPhoto的过程中,经常会看到这种现象,如果通知iPhoto仅显示等级为三星级或三星级以上的图片,则指定的条件为“照片的等级必须为三星级或三星级以上”。这样,所有照片都需要经过该过滤器过滤。满足条件的对象通过了过滤器,而其他对象被筛除了。最后,iPhoto将显示出所有高质量的图片。</p> <p>Cocoa提供了一个名为NSPredicate的类,它用于指定过滤器的条件。可以创建NSPredicate对象,通过该对象准确地描述所需的条件,对每个对象通过谓词进行筛选,判断它们是否与条件相匹配。这里的“谓词”通常用在数学和计算机科学概念中,表示计算真值或假值的函数。</p> <p>Cocoa用NSPredicate描述查询的方式,原理类似于在数据库中进行查询。可以在数据库风格的API中使用NSPredicate类,例如Core Data和Spotlight。可以将NSPredicate看成另一种间接操作方式。例如,如果需要查询满足条件的机器人,可以使用谓词对象进行检查,而不必使用代码进行显示查询。通过交换谓词对象,可以使用通用代码对数据进行过滤,而不必对相关条件进行硬编码。</p> <h2>创建</h2> <p>1)方式一</p> <p>创建许多对象,并将它们组合起来。如果正在构建通用用户接口来指定查询,采用这种方式比较简单。</p> <p>2)方式二</p> <p>查询代码中的字符串。</p> <pre> <code class="language-objectivec">Car *car; Car = makeCar(@"Herbie", @"Honda", @"CRX", 1984, 2, 110000, 58); [garage addCar:car]; /*构建的汽车:品牌为Herbie,型号为双门1984Honda CRX,马力引擎为58,已经行驶距离为110000英里*/ /*创建谓词*/ NSPredicate *predicate; predicate = [NSPredicate predicateWithFormat:@"name == 'Herbie'"]; </code></pre> <p>计算谓词</p> <pre> <code class="language-objectivec">BOOL match = [predicate evaluateWithObject:car]; NSLog(@"%s",(match) ? "YES":"NO"); </code></pre> <p>另外一个谓词:</p> <pre> <code class="language-objectivec">NSPredicate *predicate = [NSPredicate predicateWithFormat:@"engine.horsepower >150"]; /*查看车库中哪些车的功率最大,可以循环测试每个汽车的谓词*/ NSArray *cars = [garage cars]; for(Car *car in cars){ if([predicate evaluateWithObject:car]){ NSLog(@"%@", car.name); } } </code></pre> <h2>过滤器</h2> <p>如果我们不必像上文那样编写for循环和if语句,这有什么不好?实际上,某些类别将谓词过滤方法添加到了Cocoa集合类中。 -filteredArrayUsingPredicate: 是NSArray数组中的一种类别方法,它将循环过滤数组内容,根据谓词计算每个对象的值,并将值为YES的对象累积到将被返回的新数组中:</p> <pre> <code class="language-objectivec">NSArray *results; results = [cars filteredArrayUsingPredicate:predicate]; NSLog(@"%@",results); </code></pre> <p>假如有一个可变数组,你需要剔除不属于该数组的所有项目:</p> <pre> <code class="language-objectivec">NSMutableArray *carsCopy = [cars mutableCopy]; [carsCopyfilterUsingPredicate:predicate]; </code></pre> <h2>格式说明符</h2> <p>资深编程人员都知道,硬编码并非好方法,因此,我们可以通过格式符构建谓词:</p> <pre> <code class="language-objectivec">NSPredicate *predicate = [NSPredicate predicateWithFormat:@"engine.horsepower > %d", 50]; </code></pre> <h2>运算符</h2> <p>NSPredicate的格式字符串包含大量不同的运算符。</p> <p>1)比较和逻辑运算符</p> <p>谓词字符串语法支持C语言中一些常用的运算符,例如等号运算符==和=。</p> <p>不等号运算符具有各种形式:</p> <pre> <code class="language-objectivec">>:大于 >=和=>:大于或等于 <:小于 <=和=<:小于或等于 !=和<>:不等于 </code></pre> <p>此外,谓词字符串语法还支持括号表达式和AND、OR、NOT逻辑运算符或者C样式的等效表达式&&、||和!。</p> <p>2)数组运算符</p> <p>谓词字符串“(engine.horsepower> 50) OR (engine.horsepower < 200)”是一种十分常见的模式。等效于:</p> <pre> <code class="language-objectivec">predicate= [NSPredicate predicateWithFormat:@"engine.horespower BETWEEN {50,200}"]; </code></pre> <p>花括号表示数组,BETWEEN将数组中第一个元素看成是数组的下界,第二个元素看成是数组的上界。</p> <pre> <code class="language-objectivec">NSArray *betweens = [NSArray arrayWithObjects:[NSNumber numberWithInt:50],[NSNumber numberWithInt:200], nil]; predicate = [NSPredicate predicateWithFormat:@"engine.horsepower BETWEEN %@",betweens]; </code></pre> <p>数组不仅仅用来指定某个区间的端点值。你可以使用IN运算符查找数组中是否含有某个特定值。</p> <pre> <code class="language-objectivec">predicate = [NSPredicate predicateWithFormat:@"name IN {'Herbie', 'Snugs', 'Badger','Flap'}"]; </code></pre> <p> </p> <p>来自:http://charsdavy.github.io/2017/03/28/objc-NSPredicate/</p> <p> </p>
本文由用户 cact 自行上传分享,仅供网友学习交流。所有权归原作者,若您的权利被侵害,请联系管理员。
转载本站原创文章,请注明出处,并保留原始链接、图片水印。
本站是一个以用户分享为主的开源技术平台,欢迎各类分享!