如何在Swift中从协议数组中移除元素?

16

现在Swift的协议实现让我感到非常烦恼。我有一个数组observers,它是基于自定义协议Observing定义的,我试图从该数组中删除给定元素,但是Swift会抱怨Observing没有实现Identifiable(我认为这实际上是我的另一个协议,除非也有一个系统协议叫做这个)。我只想进行引用比较并删除实际对象。我不关心对对象执行任何类型的比较。

var observers = [Observing]()

func removeObserver( observer: Observing ) {
    for i in 0 ..< self.observers.count {
        if self.observers[i] == observer { // <='Observing' is not convertible to 'Identifiable'...?
            self.observers.removeAtIndex(i)
            break
        }
    }
}

观察者对象是否有“==”比较的重载,即允许您检查对象是否实际相等? - TheCodingArt
不需要,但为什么它需要呢?我只想执行引用相等比较。在Swift中,对象不能被比较吗? - devios1
1
基于 ahruss 所提到的原因,我很高兴你找到了想要的答案。在 Objective-C 中,== 和 isEquals 是有区别的...在 Swift 中没有 isEquals,所以 == 就相当于 isEquals,而 === 则用于指针比较。 - TheCodingArt
2个回答

24
== 运算符在 Swift 中检查值相等性,但它没有默认实现。如果你想要引用相等性,你可以在 Swift 中使用 ===!==
请参阅文档获取更多细节。

身份运算符

因为类是引用类型,所以多个常量和变量可能会在后台引用同一个类的单个实例。(对于结构体和枚举来说则不然,因为它们在被分配给常量或变量、传递给函数时总是被复制。)

有时候查找两个常量或变量是否引用同一个类的确切实例是有用的。为了实现这一点,Swift 提供了两个身份运算符:

恒等于 (===) 不恒等于 (!==)

注意,为了让 === 运算符生效,对象必须符合 AnyObject 协议。你可以通过在协议后面加上 ": class" 来保证这一点。
protocol SomeProtocol : class { ... }

哦,太好了,我不知道Swift有一个===运算符(是的,我读过这本书,但可能跳过了那部分)。 - devios1
感谢您的编辑。我更喜欢使用@class_protocol而不是@objc,因为我想保持纯Swift的状态。 - devios1
4
在beta5版本中,应该写成 protocol Name: class { ... } - Ilya Belikin

3

如果你想比较两个观察点是否指向同一实例,请使用 === 运算符。这要求观察者必须符合 AnyObject。一个简单的方法来要求观察只适用于 AnyObjects 是在协议声明中添加 @class_protocol 前缀。


2
@class_protocol 不是正确的方法吗?为什么要用 @objc? - ahruss
1
看起来是这样。我不知道。谢谢你的提示。 - Connor
@class_protocol prefix deprecated, new syntax: protocol name: class {} - Andres Canella

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接