【问题标题】:NSet containsObject is giving unpredictable resultsNSet containsObject 给出了不可预测的结果
【发布时间】:2018-02-11 04:38:38
【问题描述】:

在我的以下代码中,[NSSet containsObject] 给出了不可预测的结果。我发现具有值 row,col (2,2) 的 Cell3 对象在我的 while 循环中被添加了两次。 但是,如果我在 if 条件行的 isEqual 方法中设置断点,则 (2,2) 不会被添加两次。

这个问题是否与代码优化有关。当我很久以前在 C++ 中工作时,我在调试与发布模式下看到了这些类型的问题。如果设置断点,则问题不会发生,但如果没有断点,则问题会发生。我从未在 XCode 中看到过这种问题。我正在使用 XCode 版本 9.2(9C40b)

@interface Cell3 : NSObject

@property(assign) NSInteger row;
@property(assign) NSInteger col;

-(instancetype) initWithRow:(NSInteger)row col:(NSInteger)col;
@end


@implementation Cell3

-(instancetype) initWithRow:(NSInteger)row col:(NSInteger)col
{
    self = [super init];
    if(self)
    {
        self.row = row;
        self.col = col;
    }
    return self;
}

- (BOOL)isEqual:(Cell3*)object
{
    if(self.row == object.row && self.col == object.col)
        return YES;
    else
        return NO;
}

@end


int NSSetTest()
{
    NSMutableSet *uniqueCells = [[NSMutableSet alloc]init];

    int a = 0;

    int b[9][2] = { {0,0}, {1,0}, {2,0}, {3,0}, {3,1}, {3,2}, {2,2}, {2,3}, {2,2} };

    while(a < 9)
    {
        Cell3 *cell = [[Cell3 alloc] initWithRow:b[a][0] col:b[a][1]];

        if(![uniqueCells containsObject:cell])
        {
            [uniqueCells addObject:cell];
        }
        a++;
    }

    return 0;
}

【问题讨论】:

  • 您是否也意识到您的containsObject 测试是不必要的?集合的全部意义在于一个对象不会出现两次
  • 感谢您提及。实际上,我在这里发布的是显示问题的代码版本。实际上,我正在通过检查未给我正确行为的 containsObject 来做其他事情。

标签: objective-c nsset


【解决方案1】:

问题是您的 Cell3 类缺少适当的 hash 实现。见https://developer.apple.com/documentation/objectivec/1418956-nsobject/1418859-hash

【讨论】:

  • 是的,我看到了,但我没有在 hash 方法中实现任何东西。文档指出“返回一个可以用作哈希表结构中的表地址的整数”为什么要我更改超类定义方法的实现?还有为什么当我在 isEqual 方法中设置断点时不会发生这个问题?
  • “你为什么要我改变超类定义方法的实现”因为错了。它将两个相等的 Cell3 对象放入不同的桶中,但它们必须放入同一个桶中,否则设置功能将中断(事实上已经发生了)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-01
  • 1970-01-01
  • 2016-08-24
  • 2020-05-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多