2016-04-13 58 views
2

我知道我可以覆蓋散列和isEqual來檢查2個實例的相等性。如下混淆默認isEqual和散列實現

- (BOOL)isEqual:(id)other 
{ 
    if (other == self) { 
     return YES; 
    } else if (![super isEqual:other]) { //WHAT is this line mean ? 
     return NO; 
    } else { 
     return <#comparison expression#>; 
    } 
} 

- (NSUInteger)hash 
{ 
    return <#hash expression#>; 
} 

好吧,

  1. other == self檢查兩個對象指針Xcode中有默認的片段和doucument https://developer.apple.com/library/ios/documentation/General/Conceptual/DevPedia-CocoaCore/ObjectComparison.html

  2. if ![super isEqual:other],這條線是什麼意思?如果超級對象不等於其他,返回NO?那麼它總是會返回NO,步驟3將不會被執行。

我錯了嗎?

感謝。

+0

這是檢查是否超類的實現中的isEqual:是假的。 – Tim

+0

if![super isEqual:other]:因爲您重寫了方法,因此只需調用基類方法。 –

+1

如果超類是NSObject,那麼它會檢查兩個實例的指針,這將返回false。那麼第3步不會被執行?對 ? –

回答

2

這是一個類層次結構中的典型實現,也就是說,如果您的類從具有其自己有意義的實現的超類中派生。在這種情況下,讓超類測試公共屬性的平等是明智的。如果公共部分不相等,則派生對象不可能相等。

如果您直接從NSObject派生,則不需要。

其實,你需要一個額外的步驟,以及:

- (BOOL)isEqual:(id)other 
{ 
    if (other == self) { 
     return YES; 
    } else if (![super isEqual:other]) { 
     return NO; 
    } else if (![other isKindOfClass:[MyClass class]]) { 
     return NO; // comparing incompatible objects 
    } else { 
     MyClass *myOther = (MyClass *) other; 
     return <#compare between self and myOther#>; 
    } 
} 
+0

太棒了,這是我想知道的。非常感謝 –

0

Objective-C中的Hash和isEqual之間略有不同。 首先,NSObject使用方法isEqual:檢查與另一個對象的相等性,基本上,如果兩個對象共享一組通用可觀察屬性,則兩個對象可能相等。

對象比較中的散列是確定集合成員資格的額外步驟,這會加快您的操作。

這將解釋有關哈希的isEqual和一點點

  • Object的相等是可交換的([A isEqual:方法B] - >並[b isEqual:方法A])
  • 如果對象是相等的,然後它們的散列值也必須相等([a isEqual:b] - > [a散列] == [b散列])
  • 但是,相反並不成立:兩個對象的散列值相等並不意味着他們的價值觀是平等的。

我希望這會有所幫助。作爲參考,您可以訪問此鏈接http://nshipster.com/equality/

+0

這似乎是[NSHipster文章]的總結(http://nshipster.com/equality/#equality-&-identity)。像「我希望這會有所幫助」這樣的短語使得這看起來像是剽竊。 – trojanfoe

+0

是的,並在你的答案中詳細說明。 – trojanfoe

0

讓我們看看類繼承的一個例子:現在

@interface A : NSObject 
@property (nonatomic, assign, readwrite) NSInteger fieldA; 
@end 

@interface B : A 
@property (nonatomic, assign, readwrite) NSInteger fieldB; 
@end 

,如果你想實現的A平等,那麼你要它的基礎上的平等fieldA

// A equality 
- (BOOL)isEqual:(id)other { 
    ... 

    return [self fieldA] == [other fieldA]; 
} 

當您在B實現平等,就需要兩個條件 - 首先,你必須確保fieldA都是平等的,那麼你必須確保fieldB是平等的。

// B equality 
- (BOOL)isEqual:(id)other { 
    ... 

    return [super isEqual:other] && [self fieldB] == [other fieldB]; 
} 

這正是[super isEqual:other]在做什麼 - 它會檢查超類的平等要求,那就是fieldA

說實話,這個isEqual:模板不是很好。它缺少的最重要的事情之一,就是階級平等檢查:

if (![other isMemberOfClass:[self class]]) { 
    return NO; 
} 

你不需要此檢查,只有當您不要混合使用不同類的實例。但是,當您開始將AB的實例放入相同的數組/字典等中時,嘗試將A的實例與B的實例進行比較時將會崩潰。