2009-08-06 38 views
26

Tôi có lớp mô hình cơ sở dữ liệu là NSObject. Tôi có một bộ các đối tượng này trong một số NSMutableArray. Tôi sử dụng indexOfObject: để tìm một kết quả phù hợp. Vấn đề là thay đổi địa chỉ bộ nhớ của đối tượng mô hình. Vì vậy, tôi đang ghi đè phương thức hash để trả về ID hàng của mô hình. Tuy nhiên, điều này không khắc phục được. Tôi cũng phải ghi đè phương pháp isEqual: để so sánh giá trị của phương pháp hash.NSObject isEqual: và hàm băm mặc định là gì?

Sử dụng phương pháp isEqual: để xác định sự bình đẳng theo mặc định là gì?

Tôi giả sử nó sử dụng địa chỉ bộ nhớ. Sau khi đọc tài liệu isEqual: tôi nghĩ rằng nó đã sử dụng giá trị từ phương pháp hash. Rõ ràng, đó không phải là trường hợp như nỗ lực của tôi để ghi đè lên giá trị đó đã không giải quyết vấn đề ban đầu của tôi.

+0

Có một vài câu trả lời đầu cơ ở đây. Bất cứ ai có thể cung cấp tài liệu thực tế rằng mặc định isEquals sử dụng địa chỉ> Tôi không gợi ý nó không, chỉ muốn nghe nó từ miệng của con ngựa. – DougW

+0

@ DougW Tôi chia sẻ cảm xúc của bạn về điều này, vì vậy tôi đã theo dõi một tham chiếu chính thức và chỉnh sửa nó vào câu trả lời được chấp nhận. –

+0

Bạn đang đọc tài liệu cho giao thức NSObject, không phải lớp NSObject. Giao thức xác định những gì các phương pháp nên làm, lớp không xác định những gì nó thực sự làm. Nó luôn luôn an toàn nhất để ghi đè bằng và băm để làm việc như thế nào bạn muốn họ làm việc. –

Trả lời

26

Như bạn đã đoán chính xác, hành vi mặc định của là so sánh địa chỉ bộ nhớ của đối tượng. Kỳ lạ thay, đây không phải là hiện nay được ghi lại trong NSObject Class Reference, nhưng nó được diễn tả trong tài liệu hướng dẫn Introspection, trong đó nêu:

Việc thực hiện mặc định NSObject của isEqual: chỉ đơn giản là kiểm tra bình đẳng con trỏ.

Tất nhiên, như bạn không biết, các lớp con của NSObject có thể ghi đè isEqual: để hoạt động khác. Ví dụ: NSString Phương thức isEqual:, khi được thông qua NSString khác, trước tiên sẽ kiểm tra địa chỉ và sau đó kiểm tra kết quả chính xác bằng chữ giữa các chuỗi.

+0

Một tài liệu tham khảo cho điều này sẽ được tốt đẹp. –

+1

... vì vậy tôi đã thêm một. Kỳ lạ thay, tham chiếu lớp 'NSObject' thậm chí không có một mục nhập cho' isEqual: ', hãy để một mình mô tả hành vi của nó ở bất cứ nơi nào, điều đó có vẻ như một thiếu sót rõ ràng. Tôi đã có thể theo dõi một tham chiếu chính thức trong một số trang tối nghĩa trong phần 'khái niệm' của tài liệu, mặc dù. –

+0

Tài liệu của Apple đầy rẫy các trường hợp các phương thức giao thức không được ghi trong tài liệu lớp học. (Chưa kể đến các phương thức siêu lớp.) Bạn thường phải nhìn theo rất nhiều đá để tìm tài liệu cho một phương thức nhất định. –

4

Tôi giả định rằng NSObjectisEquals sử dụng toán tử ==hash sử dụng địa chỉ bộ nhớ.

isEquals phương pháp không bao giờ nên sử dụng hash làm thử nghiệm tuyệt đối cho sự bình đẳng. Nó được đảm bảo có hai đối tượng tương tự hashCode, nếu bạn tìm kiếm đủ đối tượng (chỉ cần tạo hơn 2^32 đối tượng khác nhau và ít nhất hai đối tượng sẽ có cùng một số hash).

Nói cách khác, hash yêu cầu thông số sau: Nếu hai đối tượng bằng, thì hash cần phải bằng nhau; tuy nhiên, nếu hai giá trị hash của hai đối tượng bằng nhau, chúng không nhất thiết phải bằng nhau.

Là mẹo, bạn luôn nên ghi đè isEqualshashCode cùng nhau.

+21

"Tôi sẽ giả định" là một điều không may để bắt đầu một câu trả lời với ... –

8

Câu trả lời về việc triển khai mặc định isEqual: là toàn diện nhất. Vì vậy, tôi chỉ cần thêm ghi chú của tôi về việc triển khai mặc định là hash. Dưới đây là:

-(unsigned)hash {return (unsigned)self;} 

I. nó chỉ là giá trị con trỏ giống như được sử dụng trong isEqual:.Đây là cách bạn có thể kiểm tra này ra:

NSObject *obj = [[NSObject alloc] init]; 
NSLog(@"obj: %@",obj); 
NSLog(@"hash: %x",obj.hash); 

Kết quả sẽ là một cái gì đó như thế này:

obj: <NSObject: 0x16d44010> 
hash: 16d44010 

Trân trọng.

BTW trong iOS 8 hash đã trở thành thuộc tính không phải là phương pháp nhưng ở đó.

Các vấn đề liên quan