Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
427 views
in Technique[技术] by (71.8m points)

equality - Bug with equals operator and NSObjects in Swift 2.0?

Ok, something strange is happening when writing your own equals operator for NSObject subclasses in Swift 2.0 like this:

func ==(lhs: MyObject, rhs: MyObject) -> Bool {
    return lhs.identifier == rhs.identifier
}

For a class that looks like this:

class MyObject: NSObject {
    let identifier: String
    init(identifier: String) {
        self.identifier = identifier
    }
}

This used to work just fine in Swift 1.2 and below. It still kind of works:

let myObject1 = MyObject(identifier: "A")
let myObject2 = MyObject(identifier: "A")
let result = (myObject1 == myObject2)
// result is true

So far so good, but what if both of the variables were optionals?

let myObject1: MyObject? = MyObject(identifier: "A")
let myObject2: MyObject? = MyObject(identifier: "A")
let result = (myObject1 == myObject2)
// result is false, equals operator was never even called

And one other thing that no longer works:

let myObject1 = MyObject(identifier: "A")
let myObject2 = MyObject(identifier: "A")
let result = (myObject1 == myObject2)
// result is true
let result = (myObject1 != myObject2)
// result is true, equals operator was never even called

So apparently, != no longer calls the == operator and negates it. It seems to just compare the instances instead when using !=

All of this only happens when your class is a subclass of NSObject (directly or indirectly). When it's not, everything works just like you would expect.

Can anyone tell me if this is a new 'feature' in Swift 2.0 or just a nasty bug?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I think this behavior should be considered a bug (still present as of Xcode 7 beta 6), but there's a hopefully temporary workaround: override NSObject's -isEqual instead of implementing Swift's == operator.

class MyObject: NSObject {
    let identifier: String
    init(identifier: String) {
        self.identifier = identifier
    }
    override func isEqual(object: AnyObject?) -> Bool {
        guard let rhs = object as? MyObject else {
            return false
        }
        let lhs = self

        return lhs.identifier == rhs.identifier
    }
}

I found another reference to the problem, with more code examples, here: http://mgrebenets.github.io/swift/2015/06/21/equatable-nsobject-with-swift-2/


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...