Cocoa提供了一個(gè)名為NSPredicate的類挡逼,它用于指定過濾器的條件从祝⌒铮可以創(chuàng)建NSPredicate對(duì)象垂谢,通過它準(zhǔn)確地描述所需的條件,通過謂詞篩選每個(gè)對(duì)象疮茄,判斷它們是否與條件相匹配滥朱。
-
創(chuàng)建謂詞
首先需要?jiǎng)?chuàng)建NSPredicate對(duì)象,才能將它應(yīng)用于其他對(duì)象力试。
這種謂詞字符串看上去像是標(biāo)準(zhǔn)的C語言表達(dá)式徙邻。它的左側(cè)是鍵路徑name, 隨后是一個(gè)等于運(yùn)算符“=”, 右側(cè)是一個(gè)用單引號(hào)括起來的字符串。如果謂詞字符串中的這段文本沒有打引號(hào)畸裳,就會(huì)被當(dāng)做鍵路徑缰犁。只有打了引號(hào),它才能被當(dāng)做字符串的字面量來處理∷荩可以使用單引號(hào)也可以使用雙引號(hào)(只要前后匹配就可以了)颇象,通常,還是應(yīng)該使用單引號(hào)并徘,否則必須在字符串中對(duì)每一個(gè)雙引號(hào)進(jìn)行轉(zhuǎn)義遣钳。
-
計(jì)算謂詞
通過以上步驟可以得到一個(gè)謂詞,接下來通過某個(gè)對(duì)象來計(jì)算它麦乞。
以上計(jì)算方法的原理:若指定對(duì)象(以上方法所傳參數(shù))的屬性值與謂詞表達(dá)式的條件一致蕴茴,則返回YES, 否則返回NO.
-
數(shù)組過濾器
Cocoa某些集合類官方API包含謂詞過濾方法, 比如NSArray。
注意:① 以上分別是NSArray和NSMutableArray的一種類別方法姐直,它將循環(huán)過濾數(shù)組內(nèi)容荐开,根據(jù)謂詞計(jì)算每個(gè)對(duì)象的值,并將值為YES的對(duì)象累積到被返回的新數(shù)組中简肴。②
將valueForKey: 發(fā)送給數(shù)組時(shí)晃听,鍵將作用于數(shù)組中的每個(gè)元素。
使用謂詞確實(shí)很方便砰识,但它的運(yùn)行速度不會(huì)比你自己編寫全部代碼快能扒,因?yàn)樗鼰o法避免在所有的對(duì)象之間使用循環(huán)和對(duì)每個(gè)對(duì)象進(jìn)行某些操作。一般來說辫狼,這種循環(huán)并不會(huì)對(duì)OSX上應(yīng)用的性能產(chǎn)生很大的影響初斑,因?yàn)楫?dāng)今的計(jì)算機(jī)運(yùn)行速度非常快膨处。盡量編寫最簡(jiǎn)捷的代碼见秤。如果遇到了速度問題,可以使用Instruments來測(cè)試程序性能真椿,不過iOS程序員應(yīng)該隨時(shí)密切關(guān)注程序的性能鹃答。 -
格式說明符
硬編碼并非好辦法。(與之對(duì)應(yīng)所理解的軟編碼:動(dòng)態(tài)可調(diào)控)
可以通過兩種方式將不同的內(nèi)容放入謂詞格式字符串中:格式說明符和變量名突硝。
① 格式說明符
可以在%d或者%f格式說明符中使用數(shù)字形式的值测摔,可以使用%@插入字符串值,而%@會(huì)被當(dāng)做一個(gè)有引號(hào)的字符串解恰。
NSPredicate字符串中也可以使用%k來指定鍵路徑锋八。
② 變量名
可以使用各種對(duì)象作為變量的值。記住护盈,可以使用[NSNull null]來設(shè)置nil值挟纱。
請(qǐng)注意:不能使用“$變量名”作為鍵路徑,它只能表示值腐宋。使用謂詞格式字符串時(shí)紊服,如果想在程序中通過代碼改變鍵路徑檀轨,需要使用%k格式說明符。
謂詞機(jī)制不進(jìn)行靜類型檢查围苫。你也許會(huì)在要輸入數(shù)字的地方不小心插入字符串,這樣就會(huì)出現(xiàn)運(yùn)行時(shí)錯(cuò)誤信息撤师,或者其他不可預(yù)知的行為剂府。 -
運(yùn)算符
5.1 比較和邏輯運(yùn)算符
NSPredicate的格式字符串包含大量不同的運(yùn)算符,可以自己查看文檔學(xué)習(xí)剃盾。
謂詞字符串語法支持C語言中一些常用的運(yùn)算符腺占,例如等號(hào),或者不等號(hào)痒谴,還支持括號(hào)表達(dá)式衰伯、以及邏輯運(yùn)算符。
謂詞字符串中的運(yùn)算符不區(qū)分大小寫积蔚,統(tǒng)一使用大寫字母意鲸。
不等號(hào)既適用于數(shù)字值又適用于字符串值。
5.2 數(shù)組運(yùn)算符 - 有SELF就足夠了
謂詞不僅能應(yīng)用于那些可以通過鍵路徑進(jìn)行操作的復(fù)雜對(duì)象尽爆,也能應(yīng)用于簡(jiǎn)單的值怎顾。例如,數(shù)組或者純文本的字符串漱贱,此時(shí)槐雾,用SELF代替鍵。SELF表示的是響應(yīng)謂詞計(jì)算的對(duì)象幅狮。事實(shí)上我們可以將謂詞中所有的鍵路徑表示成對(duì)應(yīng)的SELF形式募强。 - 字符串運(yùn)算符
針對(duì)字符串的關(guān)系運(yùn)算符如下
使用關(guān)系運(yùn)算符可以執(zhí)行一些有用的操作,例如使用"name BEGINSWITH 'Bad'"匹配Badger, 使用"name ENDSWITH 'vis'"匹配Elvis, 以及使用"name CONTAINS udg"匹配Judge崇摄。謂詞字符串會(huì)將Herbie與"name BEGINSWITH[cd] 'HERB'"相匹配擎值。[cd]忽略對(duì)大小寫和發(fā)音符號(hào)的區(qū)分。 - LIKE運(yùn)算符
LIKE運(yùn)算符逐抑,在該運(yùn)算符中幅恋,問號(hào)表示與一個(gè)字符匹配,星號(hào)表示與任意個(gè)字符匹配泵肄。
這種操作有時(shí)被稱為通配符捆交。
謂詞字符串"name LIKE" 'er'"將會(huì)與任何含有er的名稱相匹配。這等效于CONTAINS腐巢。
謂詞字符串"name LIKE '???er*'"將會(huì)與Paper Car相匹配品追,因?yàn)槠渲械膃r前面有3個(gè)字符,er后面有一些字符冯丙,但它與Badger不匹配肉瓦,因?yàn)锽adger的er前面有4個(gè)字符遭京。
LIKE也接收[cd]修飾符,用于忽略對(duì)大小寫和發(fā)音符號(hào)的區(qū)分泞莉。
如果你熱衷于正則表達(dá)式哪雕,可以使用MATCHER運(yùn)算符。賦給它一個(gè)正則表達(dá)式鲫趁,謂語將會(huì)計(jì)算出它的值斯嚎。
正則表達(dá)式功能非常強(qiáng)大,它是一種指定字符串匹配邏輯的非常緊湊的方式挨厚。有時(shí)堡僻,正則表達(dá)式的形式會(huì)變得復(fù)雜而費(fèi)解。NSPredicate正則表達(dá)式使用ICU語法疫剃,可搜索相關(guān)知識(shí)钉疫。雖然正則表達(dá)式的功能非常強(qiáng)大,但計(jì)算開銷非常大巢价。如果在謂詞中有某些簡(jiǎn)單的運(yùn)算符牲阁,例如基本字符串運(yùn)算和比較運(yùn)算符,那么在使用MATCHES之前可以先執(zhí)行簡(jiǎn)單的運(yùn)算壤躲,這樣將提高程序的性能咨油。