2

我正在尝试使用 NSMutableSet 创建一组对象。对象是一首歌曲,每个标签都有一个名字和一个作者。

代码:

#import "Song.h"

@implementation Song

@synthesize name,author;

-(Song *)initWithName:(NSString *)n andAuth:(NSString *)a {
    self = [super init];

    if (self) {
        name = n;
        author = a;
    }

    return self;
}

-(void)print {
    NSLog(@"song:%@; author:%@;", name,author);
}

-(BOOL)isEqual:(id)obj {
    //NSLog(@"..isEqual");

    if([[obj name] isEqualToString:name]
       && [[obj author] isEqualToString:author]) {
        return YES;
    }

    return NO;
}

-(BOOL)isEqualTo:(id)obj {
    NSLog(@"..isEqualTo");

    if([[obj name] isEqualToString:name]
       && [[obj author] isEqualToString:author]) {
        return YES;
    }

    return NO;
}

@end

然后把这个对象放入NSMutableSet:</p>

int main(int argv, char *argc[]) {
    @autoreleasepool {
        Song *song1 = [[Song alloc] initWithName:@"music1" andAuth:@"a1"];
        Song *song2 = [[Song alloc] initWithName:@"music2" andAuth:@"a2"];
        Song *song3 = [[Song alloc] initWithName:@"music3" andAuth:@"a3"];

        Song *needToRemove = [[Song alloc] initWithName:@"music3" andAuth:@"a3"];

        NSMutableSet *ns = [NSMutableSet setWithObjects:song1, song2, song3, nil];

        [ns removeObject:needToRemove];

        for (Song *so in ns) {
            [so print];
        }
    }
}

但是奇怪的事情发生了,music3还在NSMutableSet中。但是换成NSMutableArray,music3就可以删除了。NSMutableArray的removeObject调用对象的isEqual方法。我找到了removeObject的解释。就一句话:</p>

Removes a given object from the set.

不解释它是如何工作的。如何像这样删除对象?NSMutableSet的removeObject调用哪个方法?

4

1 回答 1

8

Objective-c 集合类依赖于- (NSUInteger)hash找出相等的对象。

如果您的对象返回 YESisEqual:但不同hash,则 NSSet 之类的类将认为对象不同。

参见hash的讨论:

如果两个对象相等(由isEqual:方法确定),则它们必须具有相同的哈希值。如果您在子类中定义散列并打算将该子类的实例放入集合中,那么最后一点尤其重要。

实现哈希方法。像这样的东西应该工作:

- (NSUInteger)hash {
    return [self.author hash] ^ [self.name hash];
}
于 2013-01-12T12:08:56.203 回答