NSMutableSet не сохраняет уникальные элементы - PullRequest
0 голосов
/ 07 февраля 2011

У меня есть собственный класс под названием «Сайт»:

#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;
}

- (NSString*) 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

У меня есть NSMutableSet с именем allSites, к которому я добавляю другие наборы сайтов с помощью метода unionSet. Это работает, и наборы сайтов все добавляются в набор allSites. Но дубликаты сайтов не удаляются. Я подозреваю, что это как-то связано с ошибкой с моей стороны в реализации isEqual или хэш-кода Site, которую, как я понимаю, NSMutableSet использует для обеспечения уникальности.

Любое понимание будет с благодарностью.

Ответы [ 3 ]

1 голос
/ 07 февраля 2011

Изменение метода isEqual:

- (BOOL)isEqual:(id)other {
    if (other == self)
        return YES;
    if ([[self name] isEqualToString:[other name]])
        return YES;
    return [super isEqual:other];
}
0 голосов
/ 07 февраля 2011

Суперкласс - NSObject.Я следовал рекомендованной Apple реализации isEqual:

http://developer.apple.com/library/ios/#documentation/General/Conceptual/DevPedia-CocoaCore/ObjectComparison.html

Я не был слишком знаком с реализацией NSObject isEqual.

@ phix23.Да, это работает.@ Дирк, спасибо за объяснение.Спасибо огромное, ребята, вы просто сэкономили мне кучу времени в отладчике.

0 голосов
/ 07 февраля 2011

Какой суперкласс вашего Site класса? Вызов метода isEqual: суперкласса выглядит несколько подозрительно, в частности, если ваш класс является прямым потомком NSObject. В этом случае [super isEquals: other] сводится к self == other, что явно не то, что вы хотите. Это обсуждается, например, в рекомендациях по кодированию какао :

По умолчанию isEqual: ищет равенство указателей адреса каждого объекта, а хэш возвращает значение хеш-функции на основе адреса каждого объекта, поэтому этот инвариант имеет место.

Это только предположение, хотя ...

...