2016-04-13 16 views
2

2 tane eşitliği kontrol etmek için hash ve isEqual'u geçersiz kılabileceğimi biliyorum. TamamVarsayılan isEqual ve karma ile ilgili karışıklık

- (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 çek iki nesnelerin işaretçileri şöyle Xcode varsayılan pasajı ve doucument https://developer.apple.com/library/ios/documentation/General/Conceptual/DevPedia-CocoaCore/ObjectComparison.html sahiptir.

  2. ![super isEqual:other] ise, bu satırın anlamı nedir? Süper nesne diğerine eşit değilse, HAYIR? Daha sonra her zaman NO dönecektir, 3. adım çalıştırılmayacaktır.

Yanlış mıyım?

Teşekkürler.

+0

:

Aslında siz de fazladan bir adım gerekir. – Tim

+0

if! [Super isEqual: other]: yöntemleri geçersiz kıldığınızda, temel sınıf yöntemini çağırır. –

+1

Süper sınıf, NSObject ise, bu durumda iki örnek 'işaretçisi denetler; Daha sonra 3. adım uygulanmayacak mı? sağ ? –

cevap

2

Sınıf hiyerarşisinde tipik bir uygulama, yani sınıfınız kendi anlamlı isEqual: uygulamasına sahip bir süper sınıftan geliyorsa. Bu durumda süper sınıfın ortak özelliklerin eşitliğini test etmesine izin vermek akıllıca olacaktır. Ortak kısım eşit değilse, türetilen nesnelerin eşit olma ihtimali yoktur.

Doğrudan NSObject'dan türetmeniz gerekmiyor. yanlıştır: IsEqual ait üst sınıfının en uygulaması eğer kontrol ediyor

- (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

Harika, bilmek istediğim şey bu. Çok teşekkürler –

0

Objective-C'de Hash ve isEqual arasında biraz farklıdır. Her şeyden önce, NSObject, isEqual: yöntemiyle başka bir nesneyle eşitliği denetler ve temel olarak iki nesne, gözlenebilir bir gözlemlenebilir özellik kümesini paylaşıyorlarsa diğerine eşit olabilir.

Nesne karşılaştırmasında karmalama, toplama işlemini belirlemede ekstra bir adımdır, bu da işleminizi hızlandıracaktır.

Bu

  • Nesne eşitlik değişmeli karma ve IsEqual hakkında biraz açıklar ([a IsEqual b] -> [IsEqual b:])
  • nesneler daha sonra, eşitse onların karma değerlerinin de eşit olması gerekir ([a isEqual: b] -> [a hash] == [b karma]
  • Bununla birlikte, soran aşağıdakileri yapmaz: iki nesnenin karma değerleri eşit değildir Değerlerinin eşit olması.

Umarım bu yararlı olur. Eğer A üzerinde eşitlik uygulamak istiyorsanız

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

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

Şimdi, o zaman eşitliği üzerine dayandırmak istiyorum: Referans olması için, http://nshipster.com/equality/

+0

Bu, [NSHipster makalesi] 'nin bir özeti gibi görünüyor (http://nshipster.com/equality/#equality-&-identity). "Umarım bu yararlı olur" gibi ifadeler, bunu açık bir intihal gibi gösterir. – trojanfoe

+0

Evet ve cevabınızda detay için kredi verin. – trojanfoe

0

sınıf miras biri örneğe atalım bu bağlantıyı ziyaret edebilirsiniz fieldA:

Eğer B üzerine eşitliği uygulamaktadır
// A equality 
- (BOOL)isEqual:(id)other { 
    ... 

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

, iki koşullar gerekir - öncelikle fieldA eşit olduğundan emin olmak zorunda ve sonra zorunda fieldB'un eşit olduğundan emin olun. [super isEqual:other] ne yaptığını tam olarak

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

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

- bu üst sınıfın eşitlik şartını denetleyen, yani fieldA olduğunu.

Dürüst olmak gerekirse, bu isEqual: şablonu çok iyi değil.En önemli şeylerden biri eksik ve o sınıf eşitlik çek: Farklı sınıfların örneklerini karıştırmak asla sadece olduğunda bu onay gerekmez

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

. Ancak, A ve B örneklerini aynı diziye/sözlük vb. Içine koymaya başladığınızda, A örneklerini B örnekleriyle karşılaştırmaya çalışırken çökeceksiniz.