NSMutableSet 不保持元素唯一

发布于 2024-10-16 09:17:54 字数 1616 浏览 3 评论 0原文

我有一个名为“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;
}

- (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

我有一个名为 allSites 的 NSMutableSet,我通过 unionSet 方法向其中添加其他站点集。此操作有效,并且站点集全部添加到 allSites 集中。但重复的站点不会被删除。我怀疑这与我在 Site 的 isEqual 或 hashcode 实现中的错误有关,我理解 NSMutableSet 使用它来确保唯一性。

任何见解将不胜感激。

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

- (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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

孤千羽 2024-10-23 09:17:54

更改 isEqual 方法:

- (BOOL)isEqual:(id)other {
    if (other == self)
        return YES;
    if ([[self name] isEqualToString:[other name]])
        return YES;
    return [super isEqual:other];
}

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];
}
三月梨花 2024-10-23 09:17:54

您的 Site 类的超类是什么?对超类的 isEqual: 方法的调用看起来有点可疑,特别是如果您的类是 NSObject 的直接后代。在这种情况下,[super isEquals: other] 本质上可以归结为 self == other,这显然不是您想要的。例如,在 可可的编码指南

默认情况下 isEqual:查找每个对象地址的指针是否相等,并且 hash 根据每个对象的地址返回一个哈希值,因此这个不变量成立。

这只是一个猜测,不过……

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...

摘星┃星的人 2024-10-23 09:17:54

超类是 NSObject。我遵循苹果推荐的 isEqual 实现:

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

我不太熟悉 NSObject isEqual 实现。

@phix23。是的,这有效。 @Dirk,感谢您的解释。非常感谢大家,你们在调试器中为我节省了很多时间。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文