2016-06-21 7 views
-1

Я пытался реализовать расширение протокола и протокола, которое предоставляет метод по умолчанию == в режиме быстрого. Что-то вроде этого:Реализация метода равных по умолчанию для протокола

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 
    } 

} 

Я не могу найти никакой документации по порядку старшинства, когда существует множество реализаций для ==. Это только мой опыт.


Edit: вместо определения == для протокола, определить собственный базовый класс для переопределения NSObject «s поведение по умолчанию:

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 (объект: AnyObject?) -> Bool для расширения протокола не получает ни –

+0

, но и переопределяет метод, но я пытался сделать протокол таким образом, чтобы любой объект, который соответствовал протоколу, мог использовать тот же isEqual без подкласса –

Смежные вопросы