为协议实现默认等于方法

时间:2016-06-21 01:56:26

标签: ios swift

我一直在尝试实现一个协议和协议扩展,它在swift中提供了一个默认的==方法。像这样:

protocol NameProtocol: Equatable {
    func getName() -> String
}

extension NameProtocol{}

func ==<T: NameProtocol>(lhs: T, rhs: T) -> Bool{
    return lhs.getName() == rhs.getName()
}

然后是这样的一个类:

class NamedObject: NSObject, NameProtocol {

    let name: String

    init(name: String) {
        self.name = name
        super.init()
    }

    func getName() -> String {
        return self.name
    }

}

但是,永远不会调用自定义==方法:

 let one = NamedObject(name: "Name")
 let two = NamedObject(name: "Name")
 if one == two {
     NSLog("EQUAL")
 }
 else{
     NSLog("NOT EQUAL")
 }

我在这里做错了吗?

更新:

从我得到的答案看起来我想要完成的事情是不可能的。接近的唯一方法是子类(它有明显的缺点)。我要留意一个合适的解决方案。

2 个答案:

答案 0 :(得分:2)

因为超类中的==运算符优先于协议的运算符。对于NSObject==表示指针相等。

如果从NSObject删除继承,它将按预期工作:

class NamedObject: NameProtocol {

    let name: String

    init(name: String) {
        self.name = name
        super.init()
    }

    func getName() -> String {
        return self.name
    }

}

==有多个实现时,我无法找到有关优先顺序的任何文档。这只是我的经验。

编辑,而不是为协议定义==,定义您自己的基类来覆盖NSObject的默认行为:

class MyBaseClass: NSObject {
    func getName() -> String {
        fatalError("You must override this method")
    }
}

func == (lhs: MyBaseClass, rhs: MyBaseClass) -> Bool {
    return lhs.getName() == rhs.getName()
}

class NamedObject: MyBaseClass {
    let name: String

    init(name: String) {
        self.name = name
    }

    override func getName() -> String {
        return self.name
    }
}

答案 1 :(得分:0)

您的类派生自NSObject。您重写isEqual:(不是Swift ==)来更改NSObject派生类对实例相等意味着什么的想法。

然而,将此移至协议扩展的策略永远不会起作用,因为Objective-C对Swift协议扩展一无所知。位于协议扩展中的代码对于Objective-C是完全不可见的。

所以,基本上,通过使这个类派生自NSObject,你已经在脚中拍摄了你的协议扩展策略。