NSMutableSet not Keeping Elements Unique
I have a custom class called 'Site':
#import "Site.h"
#import <MapKit/MapKit.h>
@implementation Site
@synthesize name, desc, coordinate;
+ (Site*) siteWithName:(NSString *)newName
andDescription:(NSString *)newDesc
andLatitude:(double)newLat
andLongitude:(double)newLon
{
Site* tmpSite = [[Site alloc] initWithName:newName
andDescription:newDesc
andLatitude:newLat
andLongitude:newLon];
[tmpSite autorelease];
return tmpSite;
}
- (Site*) initWithName:(NSString *)newName
andDescription:(NSString *)newDesc
andLatitude:(double)newLat
andLongitude:(double)newLon
{
self = [super init];
if(self){
self.name = newName;
self.desc = newDesc;
coordinate.latitude = newLat;
coordinate.longitude = newLon;
return self;
}
return nil;
}
- (NSString*) title
{
return self.name;
}
- (NSStr开发者_如何转开发ing*) subtitle
{
return self.desc;
}
- (BOOL)isEqual:(id)other {
if (other == self)
return YES;
if (![super isEqual:other])
return NO;
return [[self name] isEqualToString:[other name]]; // class-specific
}
- (NSUInteger)hash{
return [name hash];
}
- (void) dealloc
{
[name release];
[desc release];
[super dealloc];
}
@end
I've got an NSMutableSet called allSites which I'm adding other sets of sites to via the unionSet method. This works and the sets of sites are all added to the allSites set. But duplicate sites are not removed. I suspect that this has something to do with a mistake on my part in the isEqual or hashcode implementation of Site, which I understand NSMutableSet uses to ensure uniqueness.
Any insight would be greatly appreciated.
Change the isEqual
method:
- (BOOL)isEqual:(id)other {
if (other == self)
return YES;
if ([[self name] isEqualToString:[other name]])
return YES;
return [super isEqual:other];
}
What is the superclass of your Site
class? The call to the superclass' isEqual:
method looks a little bit suspicous, in particular, if your class is a direct descendant of NSObject
. In that case, [super isEquals: other]
essentially boils down to self == other
, which is clearly not what you want. This is discussed, for example, in the coding guidelines for cocoa:
By default isEqual: looks for pointer equality of each object’s address, and hash returns a hash value based on each object’s address, so this invariant holds.
This is just a guess, though...
The superclass is NSObject. I was following apple's recommended isEqual implementation from:
http://developer.apple.com/library/ios/#documentation/General/Conceptual/DevPedia-CocoaCore/ObjectComparison.html
I wasn't too familiar with the NSObject isEqual implementation.
@phix23. Yep, this works. @Dirk, thanks for the explanation. Thanks a ton guys, you just saved me a bunch of time in the debugger.
精彩评论