[swift-users] odd `==` `!=` behavior with class that inherits `NSObject`

Nate Birkholz nbirkholz at gmail.com
Tue Apr 18 22:04:42 CDT 2017


Your issue seems to be that you created a custom implementation for the
`==` operator but not one for the `!=` operator. If I add a custom
implementation for `!=` I get the results you expected. Tthe default
implementation of NSObject's `isEqual` is a test for identity, like the
`===` in Swift. So when you ask "is `a` NOT the same object in memory as
`b`?" the object returns "true" because they are indeed not the same object.

class Foo:NSObject {

    let name:String


    init(name:String) {

        self.name = name

    }


    public static func ==(lhs: Foo, rhs: Foo) -> Bool {

        guard type(of:lhs) == type(of:rhs) else { return false }

        return lhs.name == rhs.name

    }


    public static func !=(lhs: Foo, rhs: Foo) -> Bool {

        guard type(of:lhs) == type(of:rhs) else { return false }

        return lhs.name != rhs.name

    }

}


let a = Foo(name: "bar")

let b = Foo(name: "bar")


print(a == b) // true

print(a != b) // false

On Tue, Apr 18, 2017 at 7:33 PM, Zhao Xin via swift-users <
swift-users at swift.org> wrote:

> Sample 1: both `==` and `!=` is true.
>
> import Foundation
>
>
> class Foo:NSObject {
>
>     let name:String
>
>
>     init(name:String) {
>
>         self.name = name
>
>     }
>
>
>     public static func ==(lhs: Foo, rhs: Foo) -> Bool {
>
>         guard type(of:lhs) == type(of:rhs) else { return false }
>
>         return lhs.name == rhs.name
>
>     }
>
> }
>
>
> let a = Foo(name: "bar")
>
> let b = Foo(name: "bar")
>
>
> print(a == b) // true
>
> print(a != b) // true
>
> Sample 2: Add above code to a do-block, behavior changes to expect
>
> do {
>
>     class Foo:NSObject {
>
>         let name:String
>
>
>
>         init(name:String) {
>
>             self.name = name
>
>         }
>
>
>
>         public static func ==(lhs: Foo, rhs: Foo) -> Bool {
>
>             guard type(of:lhs) == type(of:rhs) else { return false }
>
>             return lhs.name == rhs.name
>
>         }
>
>     }
>
>
>
>     let a = Foo(name: "bar")
>
>     let b = Foo(name: "bar")
>
>
>
>     print(a == b) // false
>
>     print(a != b) // true
>
> }
>
> Sample 3: A little investigation shows that `==` didn't call NSObject's `
> func isEqual(_ object: Any?) -> Bool` but `!=` did.
>
> class Foo:NSObject {
>
>     let name:String
>
>
>
>     init(name:String) {
>
>         self.name = name
>
>     }
>
>
>
>     public static func ==(lhs: Foo, rhs: Foo) -> Bool {
>
>         guard type(of:lhs) == type(of:rhs) else { return false }
>
>         return lhs.name == rhs.name
>
>     }
>
>
>
>     override func isEqual(to object: Any?) -> Bool {
>
>         print("111")
>
>         return super.isEqual(to: object)
>
>     }
>
>
>
>     override func isEqual(_ object: Any?) -> Bool {
>
>         print("2222")
>
>         return super.isEqual(object)
>
>     }
>
> }
>
>
> let a = Foo(name: "bar")
>
> let b = Foo(name: "bar")
>
>
> print(a == b) // true
>
> print(a != b) // 2222, true
>
> print(!(a == b)) // false
>
>
> So I am wondering what is the future? Will we keep on using `isEqual(_
>  object: Any?)` with class that inherits `NSObject`, or we are trying to
> drop it?
>
> Xcode  8.3.1 (8E1000a), 3.1 (swiftlang-802.0.51 clang-802.0.41), macOS 10.12.4
> (16E195)
>
> Zhaoxin
>
> _______________________________________________
> swift-users mailing list
> swift-users at swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
>
>


-- 
Nate Birkholz
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20170418/0b5f20d4/attachment.html>


More information about the swift-users mailing list