【Effective Objective-C 2.0 讀書筆記】第八條 :理解“對象等同性”這一概念

第八條 :理解“對象等同性”這一概念

根據(jù)“等同性“(equality)來比較對象是一個非常有用的功能染厅。

不過按照”==“操作符比較出來的結(jié)果未必是我們想要的捌朴,因為該操作比較的是兩個指針本身,而不是其所指的對象庞溜。應(yīng)該使用NSObject協(xié)議中聲明的”isEqual“:方法來判斷兩個對象的等同性革半。

一般來說,兩個類型不同的對象總是不相等(unequal)流码。某些對象提供了特殊的”等同性判斷方法“又官,如果已經(jīng)知道兩個受測對象都屬于同一類,那么就可以使用這種方法漫试。

NSString類實(shí)現(xiàn)了一個自己獨(dú)有的等同性判斷方法赏胚,名叫“isEqualToString:”。傳遞給該方法的對象必須是NSString商虐。調(diào)用該方法比調(diào)用“isEqual”方法快觉阅。因為isEqual方法不知道受測對象的類型。

NSObject協(xié)議中有兩個用于判斷等同行的方法:

-(BOOL)isEqual:(id)object;

-(NSUInteger)hash;

NSObject類對這兩個方法的默認(rèn)實(shí)現(xiàn)是:當(dāng)且僅當(dāng)“指針值”(pointer value)完全相等時秘车,這兩個對象才相等典勇。若想在自定義的對象中,正確復(fù)寫這些方法叮趴,就必須先理解其約定(contract)割笙。

如果isEqual:方法判定兩個對象相等,那么其hash也必須返回同一個值。

但是伤溉,如果兩個對象的hash方法返回同一個值般码,那么“isEqual:”方法未必會認(rèn)為兩者相等。

collection:array乱顾、dictionary板祝、set等數(shù)據(jù)結(jié)構(gòu)的總稱

collection在檢索hash表時,會用對象的哈希碼做索引走净。假如某個collection是用set實(shí)現(xiàn)的券时,那么set可能會根據(jù)哈希碼把對象分裝到不同的數(shù)組中。在向set中添加對象時伏伯,要根據(jù)其哈希碼找到與之相關(guān)的的那個數(shù)組橘洞,依次檢查各個元素,看數(shù)組中已有的對象是否和將要添加的對象相等说搅。如果相等炸枣,那就說明將要添加的對象已經(jīng)在set中了。如果令每個對象都返回hash碼弄唧,那么必然會產(chǎn)生性能問題适肠。

hash方法也可以這樣來實(shí)現(xiàn):

將NSString對象中的所有屬性都放在一個字符串中,然后領(lǐng)hash方法返回該字符串的hash碼套才。這樣做也符合約定迂猴,兩個相同對象會返回相同的hash碼。

但是這樣做還需負(fù)擔(dān)創(chuàng)建字符串的開銷背伴,所以比返回單一值要慢沸毁。

把這種對象放入collection中也會產(chǎn)生性能問題,因為想要添加對象傻寂,必須先計算其hash碼息尺。

另一種計算hash碼的辦法:

-(NSUInteger)hash{

NSUInteger firstNameHash = [_firstName hash];

NSUInteger lastNameHash = [_lastName hash];

NSUInteger ageHash = ?_age;

return firstNameHash ^ lastNameHash ^ ageHash;

}

這種做法既能保持高效,又能使生成的hash碼至少位于一定范圍內(nèi)疾掰,而不會過于頻繁的重復(fù)搂誉。

當(dāng)然,這種算法生成的hash碼還是會碰撞(collision)静檬,不過至少可以保證hash碼有多種可能的取值炭懊。

特定類所具有的等同性判定方法

如果某些特定類需要經(jīng)常判斷等同性,那么可能需要自己來創(chuàng)建等同性判定方法拂檩,因為無須檢測參數(shù)類型侮腹,所以能大大提升檢測速度。

在編寫判定方法時稻励,也應(yīng)一并復(fù)寫“isEqual”方法父阻。后者的常見實(shí)現(xiàn)方法為:如果受測的參數(shù)與接收該消息的對象都屬于同一個類,那么就調(diào)用自己寫的判定方法,否則就交由超類來判斷加矛。

等同性判定的執(zhí)行深度

創(chuàng)建等同性判定方法時履婉,需要決定是根據(jù)整個對象來判斷等同性,還是僅根據(jù)其中幾個字段來判斷斟览。

例如:NSArray的檢測方式為先看兩個數(shù)組所含對象的個數(shù)是否相同毁腿,若相同,則在每個對應(yīng)位置的兩個對象身上調(diào)用其“isEqual:”方法趣惠。如果對應(yīng)位置上的對象均相等狸棍,那么這兩個數(shù)組就相等身害,這叫做“深度等同性判定”(deep equality)味悄。

不過,有時候無須將所有的數(shù)據(jù)逐個比較塌鸯,只根據(jù)其中部分?jǐn)?shù)據(jù)即可判明二者是否等同侍瑟。

容器中可變類的等同性

如果在容器中放入可變類對象的時候,把某個對象放入collection中后丙猬,就不應(yīng)再改變其hash碼了涨颜。collection會把各個對象按照其hash碼分裝到不同的“箱子數(shù)組”中。如果對象的hash碼在放入”箱子“之后又變了茧球,那么其所在的這個箱子對他來說就是”錯誤“的庭瑰。

要想解決這個問題,要保證抢埋,對象的hash碼弹灭,不是根據(jù)對象的可變部分計算來的。

或者保證放入collection之后就不再改變對象內(nèi)容了揪垄。

【要點(diǎn)】

1.若想要檢測對象的”對象的等同性“穷吮,請?zhí)峁眎sEqual:“與hash方法

2.相同的對象必須具有相同的hash碼,但是兩個hash碼相同的對象卻未必相同

3.不要盲目地逐個檢測每條屬性饥努,而是應(yīng)該依照具體需求來制定檢測方案

4.編寫hash方法時捡鱼,應(yīng)該使用計算速度快而且hash碰撞幾率低的算法

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市酷愧,隨后出現(xiàn)的幾起案子驾诈,更是在濱河造成了極大的恐慌,老刑警劉巖溶浴,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件乍迄,死亡現(xiàn)場離奇詭異,居然都是意外死亡戳葵,警方通過查閱死者的電腦和手機(jī)就乓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人生蚁,你說我怎么就攤上這事噩翠。” “怎么了邦投?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵伤锚,是天一觀的道長。 經(jīng)常有香客問我志衣,道長屯援,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任念脯,我火速辦了婚禮狞洋,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘绿店。我一直安慰自己吉懊,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布假勿。 她就那樣靜靜地躺著借嗽,像睡著了一般。 火紅的嫁衣襯著肌膚如雪转培。 梳的紋絲不亂的頭發(fā)上恶导,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機(jī)與錄音浸须,去河邊找鬼惨寿。 笑死,一個胖子當(dāng)著我的面吹牛羽戒,可吹牛的內(nèi)容都是我干的缤沦。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼易稠,長吁一口氣:“原來是場噩夢啊……” “哼缸废!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起驶社,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤企量,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后亡电,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體届巩,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年份乒,在試婚紗的時候發(fā)現(xiàn)自己被綠了恕汇。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片腕唧。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖瘾英,靈堂內(nèi)的尸體忽然破棺而出枣接,到底是詐尸還是另有隱情,我是刑警寧澤缺谴,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布但惶,位于F島的核電站,受9級特大地震影響湿蛔,放射性物質(zhì)發(fā)生泄漏膀曾。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一阳啥、第九天 我趴在偏房一處隱蔽的房頂上張望添谊。 院中可真熱鬧,春花似錦苫纤、人聲如沸碉钠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至祝高,卻和暖如春栗弟,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背工闺。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工乍赫, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人陆蟆。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓雷厂,卻偏偏與公主長得像,于是被迫代替她去往敵國和親叠殷。 傳聞我的和親對象是個殘疾皇子改鲫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容