Làm thế nào để bạn ghi đè đúng isEqual:trong Objective-C? "Bắt" dường như là nếu hai đối tượng bằng nhau (như được xác định bởi isEqual:phương thức), chúng phải có cùng giá trị băm.
Phần Introspection của Hướng dẫn cơ bản về ca cao có một ví dụ về cách ghi đè isEqual:, sao chép như sau, đối với một lớp có tên MyWidget:
- (BOOL)isEqual:(id)other {
if (other == self)
return YES;
if (!other || ![other isKindOfClass:[self class]])
return NO;
return [self isEqualToWidget:other];
}
- (BOOL)isEqualToWidget:(MyWidget *)aWidget {
if (self == aWidget)
return YES;
if (![(id)[self name] isEqual:[aWidget name]])
return NO;
if (![[self data] isEqualToData:[aWidget data]])
return NO;
return YES;
}
Nó kiểm tra sự bằng nhau của con trỏ, sau đó là đẳng thức lớp và cuối cùng so sánh các đối tượng sử dụng isEqualToWidget:, chỉ kiểm tra các thuộc tính namevà data. Những gì ví dụ không hiển thị là làm thế nào để ghi đè hash.
Giả sử có những tính chất khác không ảnh hưởng đến sự bình đẳng, nói age. Không nên hashghi đè phương thức đó chỉ namevà dataảnh hưởng đến hàm băm? Và nếu vậy, bạn sẽ làm điều đó như thế nào? Chỉ cần thêm băm của namevà data? Ví dụ:
- (NSUInteger)hash {
NSUInteger hash = 0;
hash += [[self name] hash];
hash += [[self data] hash];
return hash;
}
Như vậy đã đủ chưa? Có một kỹ thuật tốt hơn? Điều gì nếu bạn có người nguyên thủy, như thế intnào? Chuyển đổi chúng để NSNumbercó được băm của họ? Hay cấu trúc như thế NSRectnào?
( Brain fart : Ban đầu được viết "bitwise HOẶC" chúng cùng với |=. Thêm vào.)
if (![other isKindOfClass:[self class]])- Về mặt kỹ thuật này có nghĩa là bình đẳng sẽ không được giao hoán. Tức là A = B không có nghĩa là B = A (ví dụ: nếu một người là lớp con của người khác)