Nsdictionary implementation principles-ios hashing hash and nscopying implementation of custom classes in IsEqual oc (isequal & Hash Implementation) http://blog.csdn.net/linshaolie/ article/details/41494303 iOS development Don't tell me you really know isequal and hash!http://m.blog.csdn.net/hx_lei/article/details/53885798http. ://WWW.JIANSHU.COM/P/915356E280FC
Nsdictionary (dictionary) uses hash table to realize the mapping and storage between key and value, and the design of hash function affects the efficiency of data lookup and access. The more evenly the data is distributed in the hash table, the higher its access efficiency. In Objective-c, the nsstring is usually used as the key value, and its internal hash function is also used to ensure that each node of the data is evenly distributed in the hash table by using the NSString object as the key value.
See one of the most common method prototypes in Nsdictionary:
[OBJC]View Plain Copy
- -(void) SetObject: (ID) anobject forkey: (id <NSCopying>) Akey;
as you can see from this method, you must follow the Nscopying protocol as the Key value. This is because within Nsdictionary, a new copy of the Akey object is copied. The AnObject object, in its interior, is a strong reference (retain or strong).
Now that you know that as a key value, you must follow the Nscopying protocol, stating that in addition to the NSString object, we can use other types of objects as key values for the nsdictionary. But that's not enough, as a key value, the type must also inherit from NSObject and overload two methods:
[OBJC]View Plain Copy
- -(Nsuinteger) hash;
[OBJC]View Plain Copy
- -(BOOL) IsEqual: (ID) object;
The hash method is used to calculate the hash value of the object, and the final hash value determines where the object is stored in the hash table. We rewrite the hash method because every key-value is deposited into nsdictionary and Nsset, The dictionary will first compare the hash of the key being inserted and all the key.hash that already exist in the dictionary, ultimately deciding whether to add a key or overwrite the original key. However, with the Key.hash comparison, sometimes 2 objects hash the same situation, it is necessary to call the IsEqual method to determine the final decision, 2 key objects are the same. Considerations for nscopying implementation of custom classes in OC (IsEqual & Hash Implementation) http://blog.csdn.net/hxmcnu/article/details/52029097
In OC, if a custom class is to be considered for assignment, persistence, saving to other containers for all cases of medium-sized object copying and comparison, here is a more comprehensive example of a custom, which is recorded only:
Custom classes:
KeyValuePairs.h:
[OBJC]View Plain Copy
- #import <Foundation/Foundation.h>
- @interface Keyvaluepairs:nsobject <NSCopying>
- @property (Nonatomic,strong) NSString *identifier;
- @property (Nonatomic,strong) NSString *name;
- @end
KEYVALUEPAIRS.M:
[OBJC]View Plain Copy
- #import "KeyValuePairs.h"
- @implementation Keyvaluepairs
- -(ID) Copywithzone: (Nszone *) zone
- {
- Keyvaluepairs *KVP = [[[Self class] allocwithzone:zone] init];
- Kvp.identifier = Self.identifier;
- Kvp.name = Self.name;
- return kvp;
- }
- -(BOOL) Isequaltokeyvaluepairs: (Keyvaluepairs *) kvp{
- if (!KVP) {
- return NO;
- }
- BOOL haveequalname = (!self.name &&!kvp.name) | | [Self.name IsEqualToString:kvp.name];
- BOOL haveequalidentifier = (!self.identifier &&!kvp.identifier) | | [Self.identifier IsEqualToString:kvp.identifier];
- return haveequalname && haveequalidentifier;
- }
- #pragma mark-nsobject
- -(BOOL) IsEqual: (ID) object{
- if (self = = object) {
- return YES;
- }
- if (![ Object Iskindofclass:[keyvaluepairs Class]]) {
- return NO;
- }
- return [self isequaltokeyvaluepairs: (Keyvaluepairs *) object];
- }
- -(Nsuinteger) hash {
- return [self.name hash] ^ [self.identifier hash];
- }
- @end
Test:
[OBJC]View Plain Copy
- Nsmutabledictionary *nameswillupdatedic = [[Nsmutabledictionary alloc] init];
- Nsmutablearray *names = [[Nsmutablearray alloc] init];
- for (int i = 0; i<1000; i++) {
- NSString *name = [NSString stringwithformat:@ "%d_zhangsan", I];
- NSString *identifier = [NSString stringwithformat:@ "%d_identifier", I];
- NSString *strobj = [NSString stringwithformat:@ "%d_strobj", I];
- Keyvaluepairs *KVP = [[Keyvaluepairs alloc] init];
- Kvp.identifier = identifier;
- Kvp.name = name;
- [Nameswillupdatedic setobject:strobj FORKEY:KVP];
- [Names ADDOBJECT:KVP];
- }
- for (int j = 0; j<1000; j + +) {
- int index = Arc4random ()%1000;
- Keyvaluepairs *KVP = [names Objectatindex:index];
- NSString *strobj = [Nameswillupdatedic OBJECTFORKEY:KVP];
- NSString *msg = [NSString stringwithformat:@ "index:%d,identifier:%@,email:%@,strobj:%@", Index,kvp.identifier, Kvp.name,strobj];
- NSLog (@ "%@", msg);
- }
Note: 1. Why must the custom class implement the Nscopying protocol? This is because by Key-value 2 objects into the dictionary, the dictionary will copy the key to the operation, and the value object to retain operation, if the custom class does not implement the copy protocol, then it cannot be used as the Dictionary key object. 2, if the custom class does not rewrite IsEqual, then by default uses the memory address compares two objects, may have the unexpected result 3, isequal and the hash method to rewrite at the same time, otherwise the IsEqual method judgment will be incorrect
Nsdictionary implementation principle-ios hashing hash and isequal