2012-09-13 8 views
5

Giả sử tôi có một đối tượng được gọi là Person có thuộc tính socialSecurityNumber và lớp này ghi đè phương thức isEqual: để trả về true khi thuộc tính số an sinh xã hội bằng nhau. Và nói rằng tôi đã đặt một loạt các trường hợp của Person vào một NSDictionary.ObjectForKey của NSDictionary có dựa vào danh tính hoặc bình đẳng không?

Nếu bây giờ tôi tạo một đối tượng newPerson đó xảy ra để có số an sinh xã hội giống như một đã có trong từ điển, và tôi làm [myDictionary objectForKey:newPerson], nó sẽ sử dụng các isEqual: và return YES, hoặc nó sẽ so sánh con trỏ và trở về KHÔNG?

Tôi biết tôi có thể viết một bài kiểm tra đơn giản để tìm hiểu, nhưng tôi muốn hiểu chính xác cách objectForKey: tìm thấy kết quả phù hợp trong từ điển và nói chung là mức độ nhất quán giữa ca cao (ví dụ: indexofObject:?)

Trả lời

10

NSDictionary hoạt động như một thẻ bắt đầu bằng #. Vì vậy, nó sử dụng cả hai -hash-isEqual: để tìm đối tượng trong từ điển tương ứng với khóa đã cho.

Vì vậy, để trả lời câu hỏi của bạn cho NSDictionary, điều này sử dụng isEqual: và không so sánh con trỏ. Nhưng bạn cũng nên triển khai hash ngoài isEqual: trên lớp Person của bạn để hoạt động này hoạt động.

Một cặp khóa-giá trị trong vòng một từ điển được gọi là một mục. Mỗi mục bao gồm một đối tượng đại diện cho khóa và đối tượng thứ hai là giá trị của khóa đó. Trong từ điển, các phím là duy nhất. Tức là, không có hai khóa nào trong một từ điển đơn đều bằng nhau (được xác định bởi isEqual :).

Nếu hai vật đều bình đẳng, họ phải có giá trị hash giống nhau. Điểm cuối cùng này đặc biệt quan trọng nếu bạn định nghĩa isEqual: trong một lớp con và có ý định đặt các cá thể của phân lớp đó vào một tập hợp. Hãy chắc chắn rằng bạn cũng xác định hàm băm trong lớp con của bạn.

Bắt đầu từ chỉ số 0, mỗi phần tử của mảng được gửi một isEqual: Thông báo cho đến khi một hợp được tìm thấy hoặc cuối của mảng là đạt. Phương thức này chuyển tham số anObject cho mỗi thông báo isEqual:. Các đối tượng được coi là bằng nhau nếu isEqual: (được khai báo trong giao thức NSObject) trả về YES.


Bạn nên luôn luôn đọc tài liệu: như đã chỉ ra bởi các chất chiết xuất trích dẫn ở trên, các loại chi tiết thường được giải thích trong "Thảo luận" hoặc "Xem xét đặc biệt" các phần của tài liệu hướng dẫn phương pháp hoặc trong phần "Tổng quan" của tài liệu lớp học.

+0

Làm cách nào để triển khai băm? –

+0

Như bạn muốn miễn là 2 objets bằng nhau có cùng một băm, và rằng băm không quá phức tạp để tính toán. Thuật toán được sử dụng cho điều đó tùy thuộc vào bạn, nhưng hai đối tượng có giá trị băm khác nhau sẽ luôn được xem là khác nhau và hai objets có cùng giá trị băm sẽ được coi là có khả năng bằng nhau và sẽ gọi 'isEqual:' để đảm bảo chúng thực sự là bình đẳng. Điều này cho phép so sánh rất nhanh và tra cứu từ điển bằng cách chỉ so sánh giá trị băm (chỉ là số nguyên) và chỉ tham gia vào so sánh thực với 'isEqual:' khi băm là bằng nhau. – AliSoftware

+0

Ví dụ, đối với một chuỗi, ta có thể thực hiện phương thức 'hash' bằng cách trả về độ dài của chuỗi. Hai chuỗi bằng nhau sẽ có cùng một băm và 2 chuỗi khác nhau sẽ có các giá trị băm khác nhau. Một số chuỗi khác (như '@" bar "' và '@" baz "') sẽ vẫn có cùng giá trị băm, nhưng đó không phải là một vấn đề, trong trường hợp đó 'isEqual:' sau đó sẽ tạo một ký tự phân tích sâu hơn để kiểm tra sự bình đẳng. Nhưng so sánh này (tốn nhiều thời gian hơn) sẽ chỉ được thực hiện để so sánh các chuỗi có cùng độ dài: chuỗi có độ dài khác nhau sẽ trả về 'NO' nhanh hơn. – AliSoftware

1

cách nhất quán này là trên Cocoa (ví dụ: không NSArray của indexofObject: làm việc giống nhau không?)

Đó là nhất quán và đồng thời nó không phải là. Ý tôi là có hai phương pháp có thể được sử dụng: isEqualhash. Bạn không nên quá lo lắng về việc được sử dụng khi nào. Thay vào đó, những gì bạn nên tập trung vào là tôn trọng các yêu cầu giao thức NSObject và đảm bảo rằng nếu hai đối tượng bằng nhau theo isEqual, chúng cũng có cùng giá trị băm.

Từ isEqual documentation in the NSObject Protocol Reference

Nếu hai vật đều bình đẳng, họ phải có giá trị hash giống nhau. điểm cuối này đặc biệt quan trọng nếu bạn định nghĩa isEqual: trong một lớp con và có ý định đặt các cá thể của phân lớp đó vào bộ sưu tập . Hãy chắc chắn rằng bạn cũng xác định hàm băm trong lớp con của bạn.

+0

Hai chú thích: Một, NSArray có phương thức thứ hai là "indexOfObjectIdenticalTo:" tìm đối tượng _same_, đó là cùng một đối tượng con trỏ. Hai đối tượng NSString * khác nhau chứa "foo" sẽ được xem là khác nhau. Hai, việc thực hiện mặc định của hash và isEqual: sử dụng con trỏ làm khóa băm và so sánh con trỏ. Ví dụ: NSWindow/UIWindow có thể được sử dụng làm khóa trong từ điển và các con trỏ sẽ phải giống nhau. – gnasher729