2017-10-19 2 views
2

Swift 클래스는 타입 다운 캐스팅이 완료되면 원래 메소드를 호출 할 수 없습니다.타입 다운 캐스팅은 Swift에서 원래의 메소드를 찾을 수 없습니다.

AFAIK, 클래스 포인터로 C/C++에서 동일한 작업을 수행 할 수 있습니다.

하자 코드 회담 :

protocol MyProtocol { 
    func log() 
} 

class MyClass: MyProtocol { 
} 

class MyGenericClass<T>{ 
    init(_ t: T) {} 
} 

extension MyGenericClass: MyProtocol { 
    func log() { 
     print("MyGenericClass MyProtocol") 
    } 
} 

extension MyGenericClass where T==Int { 
    func log() { 
     print("MyGenericClass<Int>") 
    } 
} 

extension MyProtocol { 
    func log() { 
     print("MyProtocol") 
    } 
} 
extension MyProtocol where Self==TestSwift.MyGenericClass<Int> { 
    func log() { 
     print("MyProtocol where MyGenericClass<Int>") 
    } 
} 

extension MyProtocol where Self==MyClass { 
    func log() { 
     print("MyProtocol where MyClass") 
    } 
} 

func logByProtocol(_ p: MyProtocol) { 
    p.log() 
    print("Type of p is: \(type(of: p))") 
} 

let myGenericClassNumber = MyGenericClass(1) 
let myGenericClassString = MyGenericClass("1") 
let myClass = MyClass() 


myGenericClassNumber.log()//expect "MyGenericClass<Int>" 
myGenericClassString.log()//expect "MyGenericClass MyProtocol" 
myClass.log()//expect "MyProtocol where MyClass" 

logByProtocol(myGenericClassNumber)//expect "MyGenericClass<Int>", BUT "MyGenericClass MyProtocol" 
logByProtocol(myGenericClassString)//expect "MyGenericClass MyProtocol" 
logByProtocol(myClass)//expect "MyProtocol where MyClass" 

내가 logByProtocol(myGenericClassNumber)"MyGenericClass<Int>"를 인쇄 할 것으로 기대하지만 "MyGenericClass MyProtocol"을 인쇄합니다.

MyProtocol에 다운 캐스트가 수행되는 동안 MyGenericClass<Int>은 원래 log() 메서드를 찾을 수없는 것 같습니다.

"down" 클래스를 만들려면이 문제를 해결하는 방법은 원래 메서드를 호출 할 수 있습니까? Swift dynamic dispatch이 제네릭 제약 조건을 무시하기 때문에 이런 일이

+0

해결되었습니다. 단순히 p가 MyGenericClass 인 경우 {(! MyGenericClass로 ) .log()}'를 추가하십시오. –

+0

문자열 generic, double generic, float generic 등 많은 generics를 작성해야합니다. 해결책이 아니라 해킹입니다! – D4ttatraya

답변

0

:

MyGenericClass where T==Int 

이 확장에 전화를 파견 :

extension MyGenericClass: MyProtocol {} 

동적 파견 제가 이야기하면 logByProtocol(_) 방법을 쓴 곳이다 ; 동적 호출을 사용하여 log() 메서드를 호출합니다.

그리고이

myGenericClassNumber.log() 

가 예상대로 작동하는 이유는 MyGenericClass<Int> 객체에 log() 방법을 파견 정적되기 때문이다.

+1

그게 행동을 설명하지만, 저자의 질문에 대답하지 않습니다. – user28434

관련 문제