2016-06-21 40 views
-1

我一直在试图实现一个协议和协议扩展,它在swift中提供了一个默认的==方法。事情是这样的:为协议实现默认的equals方法

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

我在这里干什么什么了吗?

UPDATE:

从我得到的答案,它看起来像我想要做到的是不是真的有可能。唯一接近的方式是子类(它有明显的缺点)。我将继续寻找适当的解决方案。

回答

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

有什么方法可以改变这种行为吗?我真的不想失去NSObject超类方法。我基本上想提供isEqual的默认实现。 –

+0

创建您自己的基类来覆盖NSObject的行为。看到我编辑的答案 –

+0

,它的工作原理,我希望能想出一个可以应用于任何地方的通用协议,例如我可以将它应用于UIView或常规NSObject –

0

你的类从NSObject的派生。您可以覆盖isEqual:(而不是Swift ==)以更改NSObject派生类的实例相等方式的含义。

然而,你的策略是把它移到一个协议扩展上,因为Objective-C对Swift协议扩展一无所知。坐在协议扩展中的代码对Objective-C完全不可见。

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

+0

有关如何操作的示例,请参阅我的回答这里:http://stackoverflow.com/a/37900408/341994 – matt

+0

添加func isEqual(object:AnyObject?) - >布尔到协议扩展不会被调用 –

+0

是啊覆盖该方法的作品,但我试图做一个协议,以便符合协议的任何对象可以使用相同的isEqual,而不必继承子类 –