Objective-C中的NSPredicate

cact 7年前發布 | 72K 次閱讀 Objective-C開發 Objective-C

編寫軟件時,經常需要獲取一個對象集合,并通過某些已經條件計算該集合的值。你需要保留符合某個條件的對象,刪除那些不滿足條件的對象,從而提供一些有意義的對象。

在使用軟件iPhoto的過程中,經常會看到這種現象,如果通知iPhoto僅顯示等級為三星級或三星級以上的圖片,則指定的條件為“照片的等級必須為三星級或三星級以上”。這樣,所有照片都需要經過該過濾器過濾。滿足條件的對象通過了過濾器,而其他對象被篩除了。最后,iPhoto將顯示出所有高質量的圖片。

Cocoa提供了一個名為NSPredicate的類,它用于指定過濾器的條件。可以創建NSPredicate對象,通過該對象準確地描述所需的條件,對每個對象通過謂詞進行篩選,判斷它們是否與條件相匹配。這里的“謂詞”通常用在數學和計算機科學概念中,表示計算真值或假值的函數。

Cocoa用NSPredicate描述查詢的方式,原理類似于在數據庫中進行查詢。可以在數據庫風格的API中使用NSPredicate類,例如Core Data和Spotlight。可以將NSPredicate看成另一種間接操作方式。例如,如果需要查詢滿足條件的機器人,可以使用謂詞對象進行檢查,而不必使用代碼進行顯示查詢。通過交換謂詞對象,可以使用通用代碼對數據進行過濾,而不必對相關條件進行硬編碼。

創建

1)方式一

創建許多對象,并將它們組合起來。如果正在構建通用用戶接口來指定查詢,采用這種方式比較簡單。

2)方式二

查詢代碼中的字符串。

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'"];

計算謂詞

BOOL match = [predicate evaluateWithObject:car];
NSLog(@"%s",(match) ? "YES":"NO");

另外一個謂詞:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"engine.horsepower >150"];
/*查看車庫中哪些車的功率最大,可以循環測試每個汽車的謂詞*/
NSArray *cars = [garage cars];
for(Car *car in cars){
    if([predicate evaluateWithObject:car]){
        NSLog(@"%@", car.name);
    }
}

過濾器

如果我們不必像上文那樣編寫for循環和if語句,這有什么不好?實際上,某些類別將謂詞過濾方法添加到了Cocoa集合類中。 -filteredArrayUsingPredicate: 是NSArray數組中的一種類別方法,它將循環過濾數組內容,根據謂詞計算每個對象的值,并將值為YES的對象累積到將被返回的新數組中:

NSArray *results;
results = [cars filteredArrayUsingPredicate:predicate];
NSLog(@"%@",results);

假如有一個可變數組,你需要剔除不屬于該數組的所有項目:

NSMutableArray *carsCopy = [cars mutableCopy];
[carsCopyfilterUsingPredicate:predicate];

格式說明符

資深編程人員都知道,硬編碼并非好方法,因此,我們可以通過格式符構建謂詞:

NSPredicate  *predicate = [NSPredicate predicateWithFormat:@"engine.horsepower > %d", 50];

運算符

NSPredicate的格式字符串包含大量不同的運算符。

1)比較和邏輯運算符

謂詞字符串語法支持C語言中一些常用的運算符,例如等號運算符==和=。

不等號運算符具有各種形式:

>:大于
>=和=>:大于或等于
<:小于
<=和=<:小于或等于
!=和<>:不等于

此外,謂詞字符串語法還支持括號表達式和AND、OR、NOT邏輯運算符或者C樣式的等效表達式&&、||和!。

2)數組運算符

謂詞字符串“(engine.horsepower> 50) OR (engine.horsepower < 200)”是一種十分常見的模式。等效于:

predicate= [NSPredicate predicateWithFormat:@"engine.horespower BETWEEN {50,200}"];

花括號表示數組,BETWEEN將數組中第一個元素看成是數組的下界,第二個元素看成是數組的上界。

NSArray *betweens = [NSArray arrayWithObjects:[NSNumber numberWithInt:50],[NSNumber   numberWithInt:200], nil];
predicate = [NSPredicate predicateWithFormat:@"engine.horsepower BETWEEN %@",betweens];

數組不僅僅用來指定某個區間的端點值。你可以使用IN運算符查找數組中是否含有某個特定值。

predicate = [NSPredicate predicateWithFormat:@"name IN {'Herbie', 'Snugs', 'Badger','Flap'}"];

 

來自:http://charsdavy.github.io/2017/03/28/objc-NSPredicate/

 

 本文由用戶 cact 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!