包含 NSObject 子类时,Swift 2.0 Set 无法按预期工作

标签 swift set swift2 nsobject

将我们的代码库升级到 Swift2 后,我遇到了不寻常的问题。 Set 没有按预期进行减法或联合。

class A: NSObject {
    let h: Int

    init(h: Int) {
        self.h = h
    }

    override var hashValue: Int {
        return h
    }
}

func ==(lhs: A, rhs: A) -> Bool {
    return lhs.hashValue == rhs.hashValue
}

let a = A(h: 1)
let b = A(h: 1)

var sa = Set([a])
let sb = Set([b])

sa.subtract(sb).count // Swift1.2 prints 0, Swift 2 prints 1

sa.contains(a) // Swift1.2 true, Swift 2 true
sa.contains(b) // Swift1.2 true, Swift 2 false

看起来 new Set 没有使用 hashValue 进行内部操作。任何想法是一个错误,还是解决此问题的方法?

最佳答案

我试了一下你的代码。我能够通过不再子类化 NSObject,而是遵循 Hashable 协议(protocol)来让它工作:

class A: Hashable {
    let h: Int

    init(h: Int) {
        self.h = h
    }

    var hashValue: Int {
        return h
    }

}

func ==(lhs: A, rhs: A) -> Bool {
    return lhs.hashValue == rhs.hashValue
}

let a = A(h: 1)
let b = A(h: 1)

var sa = Set([a])
let sb = Set([b])

sa.subtract(sb).count // Swift1.2 prints 0, Swift 2 prints 1

sa.contains(a) // Swift1.2 true, Swift 2 true
sa.contains(b) // Swift1.2 true, Swift 2 false

a.hashValue == b.hashValue

当您从 NSObject 继承时,您的 == 重载实际上并没有被执行。如果你想让它与 NSObject 一起工作,你必须重写 isEquals:

override func isEqual(object: AnyObject?) -> Bool {
    if let object = object as? A {
        return object.h == self.h
    } else  {
        return false
    }
}

关于包含 NSObject 子类时,Swift 2.0 Set 无法按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32726524/

相关文章:

ios - 使用相同的全局变量实例化多个 View Controller

c++ - 如何获取集合中某个位置的整数?

ios - 将 JSON 转换为自定义对象时出错

iOS Swift 2 - 删除 tableView 行时出错

ios - 使用 Swift 的 Lumberjack 2.0 记录器

ios - 快速上传图像到FTP服务器

java - 根据两个属性折叠对象的 ArrayList 以生成唯一的集合

ios - Swift 字典获取值的键

swift - 无法将类型 'NSRange'(又名“_NSRange”)的值转换为预期参数类型 'Range<Data.Index>'(又名“Range<int>

python - 什么符号 |在 Python 中是什么意思?