2017-01-09 9 views
1

Вопрос относится к Swift3. Начиная с версии 4 вы можете, наконец, бросить объекты Type<Protocol> так:Как передать протокол NSObject <Protocol> для доступа к ограниченному интерфейсу расширения?

someObject as (Type & Protocol) 

У меня есть протокол и несколько типов наследования от него.

A, B, C, D: CKEntity (pseudocode) 

Для этого протокола у меня есть случай, когда объект наследует от NSObject:

Расширения является:

extension CKEntity where Self : NSObject { 

static func method() { 
    ... 
} 

Работы perferctly для нескольких случаев.

И у меня есть функция, которая принимает класс (тип), который реализует CKEntity.

Мне нужно проверить, соответствует ли он случаю, если это также NSObject. И если это так, вызовите соответствующую функцию.

Прототип того, что я пытаюсь выполнить:

func validateSync(ofType type: CKEntity.Type) { 
    let a = (type as NSObject.Type & CKEntity.Type).self 

    a.method() // Compilation error: Type 'Any' has no member 'method' 
} 

не работает.

Вопрос:

Как бросить тип (Protocol.Type) в NSObject.Type (не экземпляр) для удовлетворения ограничений расширения?


Сценарий (повторение):

  1. расширение для А, где А представляет собой В

  2. может быть B

  3. Нужно отдать А А: В и ограничено A & B интерфейс.

ответ

0

Решение было найдено.

Дело в том, что, когда речь заходит о расширении NSObject, что предпочтительнее прибегнуть к расширению NSObjectProtocol, а не самого NSObject (даже если вы собираетесь продлить последний).

Причина, заключающаяся в том, что сам NSObject не является протоколом, что затрудняет проверку составного протокола Swift. NSObjectProtocol, с другой стороны, естественно унаследован любым объектом, основанным на NSObject, и является протоколом, который является ключом.

Таким образом, это то, где мы должны реорганизовать вещи на понижающий тип до нескольких протоколов, если это возможно (и это возможно, если речь идет о NSObject).

Extension был изменен следующим образом:

extension NSObjectProtocol where Self : CKEntity { 
    static func method() { 
     // ... 
    } 
} 

И чек:

if let extendedType = type as? NSObjectProtocol & CKEntity.Type { 
    extendedType.self.method() 
} 

И это работает!

Недостаток можно наткнуться бы тот, который NSObjectProtocol не содержит методы КВЦ, так что вам нужно будет бросить свои объекты, как это, чтобы получить интерфейс KVC:

extension NSObjectProtocol where Self : CKEntity { 

    static var staticVar : String { 
     return (Self.self as! NSObject.Type).className() 
    } 


    var publicVar : String! { 
     return (self as! NSObject).value(forKey: "Key") as! String 
    } 
}