[swift-users] Set with element of NSObject subclasses didn't work as expected
Zhao Xin
owenzx at gmail.com
Tue Mar 28 22:20:41 CDT 2017
Turns out that for `NSObject`, protocol `Equatable` wasn't used. Instead,
it used `NSObjectProtocol.isEqual(_ object: Any?)`. Also, override `func
isEqual(_ object: Any?) -> Bool` requires to override `var hash: Int { get
}` as well.
I think this behavior should be mentioned in Swift docs or manual in `Set`
section.
Below code works.
class Bar:NSObject {
let value:Int
override public var hashValue: Int { return value }
public static func ==(lhs: Bar, rhs: Bar) -> Bool {
return lhs.value == rhs.value
}
// required by NSObjectProtocol
override func isEqual(_ object: Any?) -> Bool {
if let rhs = object as? Bar {
return self == rhs
}
return false
}
override var hash: Int { return self.hashValue }
init(_ value:Int) {
self.value = value
}
}
let barSetA:Set = [Bar(8), Bar(9)]
let barSetB:Set = [Bar(9), Bar(10)]
let barResultC = barSetA.intersection(barSetB) // {{NSObject, value 9}}
let barResultD = barSetA.subtracting(barSetB) // {{NSObject, value 8}}
Gladly I find it here
<http://stackoverflow.com/questions/32726524/swift-2-0-set-not-working-as-expected-when-containing-nsobject-subclass>
.
Zhaoxin
On Wed, Mar 29, 2017 at 3:50 AM, Zhao Xin <owenzx at gmail.com> wrote:
> Please see the code first.
>
> import Foundation
>
>
> class Foo:Hashable {
>
> let value:Int
>
>
>
> public var hashValue: Int { return value }
>
> public static func ==(lhs: Foo, rhs: Foo) -> Bool {
>
> return lhs.value == rhs.value
>
> }
>
>
>
> init(_ value:Int) {
>
> self.value = value
>
> }
>
> }
>
>
> let fooSetA:Set = [Foo(8), Foo(9)]
>
> let fooSetB:Set = [Foo(9), Foo(10)]
>
> let fooResultC = fooSetA.intersection(fooSetB) // {{value 9}}
>
> let fooResultD = fooSetA.subtracting(fooSetB) // {{value 8}}
>
>
>
> class Bar:NSObject {
>
> let value:Int
>
>
>
> override public var hashValue: Int { return value }
>
> public static func ==(lhs: Bar, rhs: Bar) -> Bool {
>
> return lhs.value == rhs.value
>
> }
>
>
>
> init(_ value:Int) {
>
> self.value = value
>
> }
>
> }
>
>
> let barSetA:Set = [Bar(8), Bar(9)]
>
> let barSetB:Set = [Bar(9), Bar(10)]
>
> let barResultC = barSetA.intersection(barSetB) // Set([])
>
> let barResultD = barSetA.subtracting(barSetB) // {{NSObject, value 9},
> {NSObject, value 8}}
>
>
> Behaviors of `func intersection(Set<Set.Element>)` and `func
> subtracting(Set<Set.Element>)` were different between normal Swift class
> and NSObject subclasses. I had thought they should be the same. It seemed
> that Set<NSObject> relied on addresses of NSObject instances instead of
> their hashValues. That made the Set useless.
>
> Swift version: 3.1 (swiftlang-802.0.48 clang-802.0.48)
> Xcode 8.3 (8E162)
>
> Zhaoxin
>
>
>
>
>
>
>
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20170329/3aa444c1/attachment.html>
More information about the swift-users
mailing list