2015-08-12 4 views
3

Я пытаюсь динамически сопоставлять протокол Swift с реализацией, но я заблокирован при попытке выполнить сравнение протоколов во время выполнения - кажется, что, возможно, протоколы действительно не существуют в во время выполнения?Сравнение времени выполнения MetaTypes Swift Protocol

Некоторые примеры вещей, которые я пробовал:

var protocols[Any] 

func findProtocol(aProtocol: Any) -> Bool { 
    // Nope, protocols don't implement equatable 
    aProtocol == protocols[0] 

    // Doesn't work, unsafeAddressOf() only applies to AnyObjects 
    let pointer: UnsafePointer = unsafeAddressOf(aProtocol) 

} 

Я думаю, что я мог бы ударить границы пытаются победить систему типа ... какие-нибудь мысли?

+0

Может вы приводите пример того, как вы на самом деле заполняете этот массив протоколов? –

+0

Будет ли это 'ProtocolName.self'? –

+0

У вас есть экземпляры типов, которые соответствуют протоколу или самим типам ('SomeProtocol.self') в вашем массиве? – Qbyte

ответ

1

Если вы знаете, что вы сравниваете типам сами вы должны использовать более подходящий тип (Any.Type):

var protocolArray: [Any.Type] = [...] 

func findProtocol(aProtocol: Any.Type) -> Bool { 
    // you can do that because Any.Type has an == operator 
    return protocolArray.contains{ $0 == aProtocol } 
} 

Для Any типа вы должны бросить его:

var protocolArray: [Any] = [...] 

func findProtocol(aProtocol: Any) -> Bool { 
    return protocolArray.contains{ 
     if let p1 = $0 as? Any.Type, p2 = aProtocol as? Any.Type { 
      return p1 == p2 
     } 
     return false 
    } 
} 
+0

У меня нет реальных реализаций типов на данный момент - все, что я знаю, у меня есть протокол, для которого я прошу реализацию. Типы реализации регистрируются, когда я добавляю протоколы к рассматриваемому массиву; но вызывающий не знает, какой конкретный тип возвращается – JRaymond

+0

@JRaymond Я обновляю свой ответ для типа «Любой». – Qbyte

+0

Это хорошо работает также - я предполагаю, что предположил, что Тип распался после литья – JRaymond

1

Возможно, я немного не понимаю, что вы хотите сделать, но вы должны иметь возможность использовать отражение для этого. Как насчет чего-то подобного?

protocol One {} 
protocol Two {} 
protocol Three {} 

var protocols: [Any] = [One.self, Two.self] 

func findProtocol(aProtocol: Any) -> Bool { 

    let findMirror = Mirror(reflecting: aProtocol) 

    for checkProtocol in protocols { 
     let mirror = Mirror(reflecting: checkProtocol) 

     if findMirror.subjectType == mirror.subjectType { 
      return true 
     } 
    } 
    return false 
} 

findProtocol(One) // Returns true 
findProtocol(Two) // Returns true 
findProtocol(Three) // Returns false 
+0

Кажется, это трюк ... Мне нужно будет исследовать, является ли возвращаемый subjectType уникальным указателем; было бы удобно использовать их вместо циклов – JRaymond

+0

Казалось, что это сработало изначально (конечно, оно компилируется), но я не мог заставить его работать во время выполнения. Может, он работает только на детской площадке? – JRaymond

+0

Интересно. Если бы я знал, что вы собираетесь помещать Any.Type в массив, я бы не сделал этого таким образом. Ответ @ Qbyte более корректен в этой ситуации. Все, что я сделал, это получить базовый Any.Type в любом случае, сравнить их с этим рефлексивным подходом. –

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