2015-02-03 5 views
3

프로토콜을 준수하는 유형을 취하고이 클래스의 인스턴스를 인스턴스화하는 메소드를 작성하고 있습니다. 빌드 할 때 컴파일러가 segfault와 충돌합니다. 이 점은 99 %의 컴파일러 버그를 지적하고 싶지만, 내가하려고하는 것이 논리적으로 정확한지 또는 컴파일러에서 절대 난센스를 던지는 것에 관심이 있으며 놀라지 말아야한다. 그것을 참조하십시오. 여기 프로토콜 유형에서 클래스 인스턴스화

내가 또한 문제의 근본 인 등의 방법 매개 변수로 입력을 전달 배제하려

protocol CreatableClass { 
    init() 
} 

class ExampleClass : CreatableClass { 
    required init() { 

    } 
} 

class ClassCreator { 
    class func createClass(classType: CreatableClass.Type) -> CreatableClass { 
     return classType() 
    } 
} 

ClassCreator.createClass(ExampleClass.self) 

내 코드는 다음과 같은 코드는 컴파일러 충돌 :

protocol CreatableClass { 
    init() 
} 

class ExampleClass : CreatableClass { 
    required init() { 

    } 
} 


let classType: CreatableClass.Type = CreatableClass.self 
let instance = classType() 

그래서 - 이것은 단순한 컴파일러 버그이며 내가하려고하는 것이 합리적인 것처럼 보이는지, 아니면 내 구현에 잘못된 것이 있습니까?

편집 :

이 아래와 같이 @Antonio으로 제네릭을 사용하여 달성 할 수 있지만, 불행하게도 난 내 응용 프로그램에 유용하지 않습니다 믿을 .

이 작업을 수행하는 실제 비 무식하게 아래로 사용 케이스 내가 일반적으로 할

protocol CreatableClass {} 
protocol AnotherProtocol: class {} 

class ClassCreator { 
    let dictionary: [String : CreatableClass] 

    func addHandlerForType(type: AnotherProtocol.Type, handler: CreatableClass.Type) { 
     let className: String = aMethodThatGetsClassNameAsAString(type) 
     dictionary[className] = handler() 
    } 

    required init() {} 
} 
+0

을하는 방법을 사용 매우 유사한 문제에 대한 자세한 논의는 http://stackoverflow.com/a/27574558/97337을 참조하십시오. 이 경우의 대답은 필요한 것을 구성 할 수있는 클로저를 전달하는 것이 었습니다. 즉, 특정 경우에 처리기가 클래스의 형식이 아니라 단지'CreatableClass' 인 경우 작동 할 것입니다. 그래서 저는 이것보다 더 많은 질문이 있다고 가정합니다. –

답변

2

같은 것입니다 그 일반적인 방법을 정의하여. 이 시도 :

class func createClass<T: CreatableClass>(classType: T.Type) -> CreatableClass { 
    return classType() 
} 

업데이트 가능한 해결 방법은 유형 클래스의 인스턴스를 생성하기보다는 통과 클로저를 전달하는 것입니다

:이다이 경우

class ClassCreator { 
    class func createClass(instantiator:() -> CreatableClass) -> (CreatableClass, CreatableClass.Type) { 
     let instance = instantiator() 
     let classType = instance.dynamicType 

     return (instance, classType) 
    } 
} 

let ret = ClassCreator.createClass { ExampleClass() } 

장점을 예를 들어, 사전에 클로저를 저장할 수 있으며 키를 알고 (클래스 이름과 1 : 1 관계에있는) 항목을 필요에 따라 더 많은 인스턴스를 만들 수 있습니다.

나는 약간 들어 ... 내 요구는 사용할 수 없습니다 만들고, 나는 그것이 단지 생각 @ objc 호환 클래스에서만 작동 실현 몇 달 전에 개발 작은 의존성 주입 프레임 워크에

+0

다른 날 이것은 내 문제의 올바른 해결책이 될 것이지만, 나의 특정한 사용 사례에서는 그것을 사용할 수 없다. 가능한 한 간단하게 질문을하기 위해 가능한 한 코드를 멍청하게하려고했지만 실제 유스 케이스는 두 가지 유형을 취하고 하나를 인스턴스화하고 다른 인스턴스를 사전에 인스턴스화 된 클래스의 키로 사용하는 메소드입니다. 나는 이것이 우리가 제네릭을 가지고있는 지금 약간의 관련이 있다고 생각한다. 그리고 나는 그 질문을 수정할 것이다! –

+1

순수한 신속한 작업을하는 다른 방법이 없습니다 (여기에 잘못 될 수 있기를 바랍니다). 아마도 objc 브리징을 사용할 수 있지만 가격은 프로토콜과 콘크리트 유형을 모두 @objc로 표시해야합니다. 따라서 모든 신속한 특정 기능이 손실됩니다. – Antonio

+0

글쎄, 아직 작동하지 않을 것이라고 확신하지는 않지만 현재 소스 코드에 액세스 할 수는 없습니다. 나는 내일까지 알 것이다!관심이 있으시면 위의 편집을 참조하십시오. –