No matter what language we use, there is always the need to determine whether two objects are equal, OC of course is no exception. First look at a piece of code:
NSString *str1 = [[NSString alloc] initWithCString:"equal" encoding:NSUTF8StringEncoding];
NSString *str2 = @"equal";
if(str1 == str2)
{
NSLog(@"equal");
}
It is clear that str1 and str2 are "equal" when we are apart. But in fact equal is not going to be printed. This is because if we are directly comparing two objects for equality, we are actually comparing pointers for two objects for equality.
In the code above, str1 and str2 are pointing to two different pieces of memory, so it's definitely not like waiting.
Let's change the code a little bit and look at:
NSString *str1 = [[NSString alloc] initWithCString:"equal" encoding:NSUTF8StringEncoding];
NSString *str2 = @"equal";
if([str1 isEqual:str2])
{
NSLog(@"equal");
}
Pay attention to the bold statement, we use nsobject provided by the IsEqual method comparison, found that "equal" was printed out. Because IsEqual is implemented within NSString, the comparison is true if the strings are equal!
Implementation of object equivalence
After looking at the example above, we now create a class to further illustrate the equivalence
#import <Foundation/Foundation.h>
@interface EqualObject : NSObject
@property(nonatomic ,strong)NSString *name;
@end
#import "EqualObject.h"
@implementation EqualObject
@end
Defines a Equalobject class that has a Name property.
Now we create two objects to compare:
EqualObject *object1 = [EqualObject new];
EqualObject *object2 = [EqualObject new];
if([object1 isEqual:object2])
{
NSLog(@"equal");
}
The discovery that the code ran at the end did not output "equal", because the isequal approach needed to be implemented on our own. NSObject IsEqual: The default method is to compare the two objects to the address is equal, here opened two objects certainly do not want to wait.
Now we add isequal: the implementation of the method:
-(BOOL)isEqual:(id)object
{
if([self class] == [object class])
{
if(![self.name isEqual:[(EqualObject *)object name]])
{
return NO;
}
return YES;
}
else
{
return [super isEqual:object];
}
}
Here is a little explanation of why two objects are not similar to the isequal of the parent class: This is because, sometimes we can make the subclass equal to the parent class, we only need to pay attention to whether the property is the same as can be written, if not required or can not be processed by the parent class so long default is not equal.
Now we do not assign the name to the operation still has no value to print out.
To modify the client code:
EqualObject *object1 = [EqualObject new];
EqualObject *object2 = [EqualObject new];
object1.name = @"xiaoming";
object2.name = @"xiaoming";
if([object1 isEqual:object2])
{
NSLog(@"equal");
}
Found that this time is running is equal.
Customizing equivalence methods for classes
We can see NSString in addition to using isequal to compare whether it is an equal accident, you can also use the isequaltostring to compare! This is an equivalence method specifically tailored for the NSString class, providing a way to make it clear that we have implemented the IsEqual method of the object.
The following provides a custom equivalence method for Equalobject and modifies the IsEqual: method
- (BOOL)isEqualToEqualObject:(EqualObject *)object
{
if(self == object)
return YES;
if(![self.name isEqualToString:object.name])
return NO;
return YES;
}
- (BOOL)isEqual:(id)object
{
if([self class] == [object class])
{
return [self isEqualToEqualObject:object];
}
else
{
return [super isEqual:object];
}
}
The client then modifies
if([object1 isEqualToEqualObject:object2])
{
NSLog(@"equal");
}
Very smooth "equal" ...
Object Hash code
Each OC object has a hash code inside it, and when the object is stored in the collection (array,set,hashtable, etc.), then their hash code is used as a key to determine which set they should put in.
First we'll look at how the collection is stored inside
Hashcode |
Subcollection |
Code1 |
Value1,value2,value3,value4 |
Code2 |
Value5,value6 |
Code3 |
Value7 |
Code4 |
Value8,value9,value10 |
The inside of the collection is not a hash table, as we think, and it will insert the object according to Hashcode to decide which sub-collection to put in. If you want to delete or compare elements within a collection, it first finds the subcollections based on Hashcode and then compares each element of the child collection.
So if the hashcode of our objects are the same, then there will be a serious problem of efficiency,
Theoretically, we determine that the equivalent of the two object hash should be the same, and the unequal two object hash should be unequal, so that in the deposit Hashtable, such as the collection, will avoid the same object repeated additions, such as our two objects hash equal, but the actual object is unequal, Then the added time will be added to the same subcollection.
So in order to avoid this situation, we try to achieve a way to avoid duplication,
Here is a way to add a new property Age,hash implementation as follows:
- (NSUInteger)hash
{
NSUInteger nameHash = [_name hash];
NSUInteger ageHash = _age;
return nameHash ^ ageHash;
}
Object equivalence in a collection
We call the IsEqual method on Nsarray, which isequal for each object in the collection and another object in the same location: the operation, which is equal to only two sets.
In this case, the final addition of the collection is immutable, and if it is a non-denatured element, there will be an unlawful control.
For example, if we add two Nsmutablearray to the Nsset and start with two arrays, then there are two elements in set.
Then modify an array to make two equal, which is the set that will have two equal elements present!
objective-c--to determine the equivalence of objects