日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

iOS之如何实现isEqual的重写

發布時間:2024/5/21 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 iOS之如何实现isEqual的重写 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、如何重寫 hash 方法

  • 一個合理的 hash 方法要盡量讓 hash 表中的元素均勻分布,來保證較高的查詢性能。
  • 如果兩個對象可以被視為同一個對象,那么它們的 hash 值要一樣。這里給出一個普遍的算法(詳情請參考:Equality):
- (NSUInteger)hash {// 假設對象有三個屬性,那么對這三個屬性分別算出 hash 值,然后進行異或運算return [self.property1 hash] ^ [self.property2 hash] ^ [self.property3 hash];}
  • Instagram 在開源 IGListKit 的同時,建議這么寫 hash 方法:
- (NSUInteger)hash {NSUInteger subhashes[] = {[self.property1 hash], [self.property2 hash], [self.property3 hash]};NSUInteger result = subhashes[0];for (int ii = 1; ii < 3; ++ii) {unsigned long long base = (((unsigned long long)result) << 32 | subhashes[ii]);base = (~base) + (base << 18);base ^= (base >> 31);base *= 21;base ^= (base >> 11);base += (base << 6);base ^= (base >> 22);result = base;}return result;}
  • 示例:
@interface Person : NSObject@property (nonatomic, copy) NSString *name;@property (nonatomic, strong) NSDate *birthday;@end- (BOOL)isEqual:(id)object {if (self == object) {return YES;}if (![object isKindOfClass:[Person class]]) {return NO;}return [self isEqualToPerson:(Person *)object];}- (BOOL)isEqualToPerson:(Person *)person {if (!person) {return NO;}BOOL haveEqualNames = (!self.name && !person.name) || [self.name isEqualToString:person.name];BOOL haveEqualBirthdays = (!self.birthday && !person.birthday) || [self.birthday isEqualToDate:person.birthday];return haveEqualNames && haveEqualBirthdays;}
  • 分析說明:
    • == 運算符判斷是否是同一對象, 因為同一對象必然完全相同;
    • 判斷是否是同一類型, 這樣不僅可以提高判等的效率, 還可以避免隱式類型轉換帶來的潛在風險;
    • 通過封裝的 isEqualToPerson: 方法, 提高代碼復用性;
    • 判斷 person 是否是 nil,做參數有效性檢查;
    • 對各個屬性分別使用默認判等方法進行判斷;
    • 返回所有屬性判等的與結果。

二、重寫 isEqual

  • 如何寫一個合理高效的判等方法?
    • 首先對內存地址進行判斷,地址相等 return YES;
    • 進行判空處理,self = = nil || object == nil ,return NO;
    • 類型判斷,![object isKindOfClass:[self class]] , return NO;
    • 對對象的其他屬性進行判斷。
  • 根據這四個步驟,可以發現,我們都是先判斷時間開銷最少的屬性,所以對于第 4 個步驟,如果對象有很多屬性,也要依照這個原則來。
  • 比如 [self.array isEqual:other.array] && self.intVal = = other.intVal 這種寫法是不合理的,因為 array 的判等會去遍歷元素,時間開銷大。如果 intVal 不相等的話就可以直接 return NO,沒必要進行數組的判等。應該這么寫:self.intVal == other.intVal && [self.array isEqual:other.array];
- (BOOL)isEqual:(PersonModel *)object {if (self == object) {return YES;}else if (self == nil || object == nil || ![object isKindOfClass:[self class]]) {return NO;}return(_property1 == object->_property1 ? YES : [_property1 isEqual:object->_property1]) &&(_property2 == object->_property2 ? YES : [_property2 isEqual:object->_property2]) &&(_property3 == object->_property3 ? YES : [_property3 isEqual:object->_property3]);}

三、hash 與判等的關系

  • hash 方法主要是用于在 Hash Table 查詢成員用的, 那么與 isEqual() 有什么關系呢?
  • 為了優化判等的效率,基于 hash 的 NSSet 和 NSDictionary 在判斷成員是否相等時,會這樣做:
    • 集成成員的 hash 值是否和目標 hash 值相等,如果相同進入下一步,如果不等,直接判斷不相等;
    • hash 值相同的情況下,再進行對象判等,作為判等的結果。
  • 簡單地說就是:hash 值是對象判等的必要非充分條件。

總結

以上是生活随笔為你收集整理的iOS之如何实现isEqual的重写的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。