2016-06-21 44 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,而不必繼承子類 –