快速检查符合协议的两个对象是否相同

时间:2016-06-04 17:20:30

标签: swift types

我有一个协议,它构成了许多类的基础 - 在下面的示例中,StaticFileRemoteFile。我引用了一个指向协议的变量

protocol ContainerDelegate {}

protocol FileProtocol {
    var delegate: ContainerDelegate? { get set }
}

class StaticFile: NSObject, FileProtocol {
    var delegate: ContainerDelegate?
}
class RemoteFile: NSObject, FileProtocol {
    var delegate: ContainerDelegate?
}

class Container: NSObject, ContainerDelegate {
    var item: FileProtocol

    override init() {}

    func something() {
        if item.delegate !== self { // This fails
        }
    }
}

我甚至不关心类型,我只想查看委托是否不是当前对象(通过引用)。使失败线路正常工作的最佳方法是什么?

2 个答案:

答案 0 :(得分:4)

您应该尝试向上翻转delegate,然后检查是否相等:

func something() {
    if item.delegate as? Container !== self {
        print("hi")
    }
}

完整的工作代码示例

protocol ContainerDelegate {}
protocol FileProtocol {
    var delegate: ContainerDelegate? { get set }
}

class StaticFile: NSObject, FileProtocol {
    var delegate: ContainerDelegate?
}

class Container: NSObject, ContainerDelegate {
    var item: FileProtocol

    func something() {
        if item.delegate as? Container !== self {
            print("hi")
        }
    }

    override init() {
        item = StaticFile()
    }
}

let c = Container()
let c2 = Container()

c.item.delegate = c2
c.something() // hi gets printed

c.item.delegate = c
c.something() // hi does **not** get printed

答案 1 :(得分:2)

这里的问题是ContainerDelegate不要求符合类型是引用类型。您可以编写一个符合此协议的struct,并使用===!==作为结构并不合理。 (===!==运算符采用AnyObject?个参数,只有类对象可以作为AnyObject传递。)

解决此问题的一种方法是使用protocol ContainerDelegate: class {},这需要引用语义,并允许您编写item.delegate !== self

另一种方式,正如luk2302指出的那样,因为你只关心对象是否与self相同,所以你可以先尝试将它转换为与self相同的类型,然后再进行比较