Swift 2.0中equals运算符和NSObjects的错误? [英] Bug with equals operator and NSObjects in Swift 2.0?

查看:91
本文介绍了Swift 2.0中equals运算符和NSObjects的错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,像这样在Swift 2.0中为NSObject子类编写自己的equals运算符时,会发生一些奇怪的事情:

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
    }
}

这过去在Swift 1.2及更低版本中都可以正常工作.还是可以的:

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

另一件事不再起作用:

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 !=

仅当您的类是NSObject的子类(直接或间接)时,才会发生所有这些情况.否则,一切都会如您所愿.

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.

有人能告诉我这是Swift 2.0的新功能还是讨厌的错误?

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

推荐答案

不幸的是,我不知道这是否被视为功能(我不这么认为).如果任何类的子类都符合Equatable的类(例如NSObject;它会比较实际实例),则会出现此问题.因此,如果您仅覆盖"子类的==运算符,则所有其他运算符都像这样:

Unfortunately I don't know whether this is considered a feature or not (I don't think so). This problem occurs if any class subclasses a class which conforms to Equatable(like NSObject; it compares actual instances). So if you only "override" the == operator of the subclass all other operators like:

func !=<T : Equatable>(lhs: T, rhs: T) -> Bool
func ==<T : Equatable>(lhs: T?, rhs: T?) -> Bool
func ==<T : Equatable>(lhs: [T], rhs: [T]) -> Bool

其中T被限制为Equatable,Swift使用基类的==运算符.作为(耗时的)解决方法,您可以像这样重载所有必须使用的相等运算符:

where T is constrained to be Equatable Swift uses the == operator of the baseclass. As (time-consuming) workaround you can overload all the equality operators you have to use like so:

func !=(lhs: MyObject, rhs: MyObject) -> Bool { ... }
func ==(lhs: MyObject?, rhs: MyObject?) -> Bool { ... }
func ==(lhs: [MyObject], rhs: [MyObject]) -> Bool { ... }

原因

此行为的原因是,如果子类符合Equatable,则将自我需求的Self确定为此类.因此,每次使用符合Equatable的(通用)类型调用==时,它只会调用初始符合类的运算符.

The reason for this behavior is that if a subclass conforms to Equatable the Self of the self requirement is determined to be this class. So every time the == is called with a (generic) type that conforms to Equatable it only calls the operator of the initial conforming class.

这篇关于Swift 2.0中equals运算符和NSObjects的错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆