I have some problems about the NSMutableSet in Objective-C.
I learnt that the NSSet will compare the two objects' hash code to decide whether they are identical or not.
The problems is, I implemented a class that is subclass of NSObject
myself. There is a property NSString *name
in that class. What I want to do is when instances of this custom class has the same variable value of "name" , they should be identical, and such identical class should not be duplicated when adding to an NSMutableSet.
So I override the - (NSUInteger)hash
function, and the debug shows it returns the same hash for my two instances obj1, obj2 (obj1.name == obj2.name)
. But when I added obj1, obj2 to an NSMutableSet
, the NSMutableSet
still contained both obj1, obj2 in it.
I tried two NSString
which has the same value, then added them to NSMutableSet
, the set will only be one NSString
there.
What could be the solution? Thank you for any help!
The custom Class: Object.h:
#import <Foundation/Foundation.h>
@interface Object : NSObject
@property (retain) NSString *name;
@end
Object.m
@implementation Object
@synthesize name;
-(BOOL)isEqualTo:(id)obj {
return [self.name isEqualToString:[(Object *)obj name]] ? true : false;
}
- (NSUInteger)hash {
return [[self name] hash];
}
@end
and main:
#import <Foundation/Foundation.h>
#import "Object.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
Object *obj1 = [[Object alloc]init];
Object *obj2 = [[Object alloc]init];
obj1.name = @"test";
obj2.name = @"test";
NSMutableSet *set = [[NSMutableSet alloc] initWithObjects:obj1, obj2, nil];
NSLog(@"%d", [obj1 isEqualTo:obj2]);
NSLog(@"%ld", [set count]);
}
return 0;
}
Instead of implementing isEqualTo:
you have to implement isEqual:
- (BOOL)isEqual:(id)object {
return [object isKindOfClass:[MyObject class]] &&
[self.name isEqual:[(MyObject *)object name]];
}
This will (probably falsely) return NO
if both self.name
and object.name
are nil
. If you want to return YES
if both properties are nil
you should use
- (BOOL)isEqual:(id)object {
if ([object isKindOfClass:[MyObject class]]) {
return (!self.name && ![(MyObject *)object name]) ||
[self.name isEqual:[(MyObject *)object name]];
}
return NO;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With