swift属性的身份比较

时间:2014-10-01 06:08:41

标签: swift

我正在尝试过滤掉数组中对象的实例(从观察者列表中删除观察者是特定的):

private var observers = [ChooserObserver]()

...

func unregisterObserver(observer: ChooserObserver ) {
    observers = observers.filter { includeElement in includeElement === observer }
}

...

protocol ChooserObserver {
    var path: String { get set }
}

不幸的是,我收到以下错误:

  

类型'ChooserObserver'不符合协议'AnyObject'

如果我尝试允许ChooserObserver像这样继承AnyObject:

protocol ChooserObserver: AnyObject {
    var path: String { get set }
}

我遇到以下错误:

  

无法声明与'AnyObject'协议的显式一致性

当我尝试强制转换为AnyObject时:

func unregisterObserver(observer: ChooserObserver ) {
    observers = observers.filter { includeElement in includeElement as AnyObject !== observer as AnyObject }
}

我收到这些错误:

  

不允许部分应用struct方法

     

不能从'ChooserObserver'转发到非@objc协议类型'AnyObject'

我只能通过将@objc附加到我的协议以及之前对AnyObject的强制转换来修复:

@objc protocol ChooserObserver {
    var path: String { get set }
}

这是必要的,如果是这样,为什么?我意识到NSMutableSet在这里可能是合适的,但我试图理解Swift的类型系统。

3 个答案:

答案 0 :(得分:3)

  

如果我尝试允许ChooserObserver继承AnyObject,如下所示:   我遇到以下错误:

正确的语法是

protocol ChooserObserver : class {
    //...
}

(可能Apple应该允许你做: AnyObject以避免需要这种新语法。)

答案 1 :(得分:1)

只是一个想法,也许它有效:

private var observerRefs = [AnyObject]()
private var observers = [ChooserObserver]()

...

func registerObserver<O where O: AnyObject, O: ChooserObserver>(observer: O) {
    observerRefs.append(observer)
    observers.append(observer)
}

func unregisterObserver<O where O: AnyObject, O: ChooserObserver>(observer: O) {
    for let index in (observerRefs.count - 1) .. 0 {
        if observerRefs[index] === observer {
            observerRefs.removeAtIndex(index)
            observers.removeAtIndex(index)
        }
    }
}

...

protocol ChooserObserver {
    var path: String { get set }
}

答案 2 :(得分:1)

协议可以通过类和值类型来实现。相同的运算符仅适用于类实例。与运算符相同必须确保两个操作数都是类。我想这就是为什么会有这样的限制。 Objective-C值类型不符合协议,这就是@objc protocol ChooserObserver工作的原因。