Swift 从协议类型实例化类

Swift 从协议类型实例化类,swift,Swift,我正在编写一个方法,该方法采用符合协议的类型并实例化这个类的一个实例。当我构建它时,编译器会因一个segfault而崩溃。我知道这99%的时间都指向编译器错误,但我很想看看我所做的是逻辑上正确的还是我只是在对编译器胡说八道,看到它崩溃我不应该感到惊讶 这是我的密码 protocol CreatableClass { init() } class ExampleClass : CreatableClass { required init() { } } class C

我正在编写一个方法,该方法采用符合协议的类型并实例化这个类的一个实例。当我构建它时,编译器会因一个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() {}
}

我通常通过定义一个泛型方法来实现这一点。试试这个:

class func createClass<T: CreatableClass>(classType: T.Type) -> CreatableClass {
    return classType()
}
这种情况的优点是,例如,您可以将闭包存储在字典中,只需知道键(与类名的关系为1:1)即可根据需要创建更多实例


我在几个月前开发的一个小型依赖注入框架中使用了该方法,我意识到它只适用于@objc兼容的类,因此无法满足我的需要……

改天,这将是解决我问题的正确方法,但在我的特定用例中,我无法使用它们。我试图尽可能地简化我的代码,使问题尽可能简单,但实际的用例是一个方法,它采用两种类型,实例化一种,并使用另一种作为字典中实例化类的键。我想这是有点相关的,现在我们有了泛型,我会修正这个问题!在纯swift中,我看不到任何其他方法可以做到这一点(希望这里是错误的)-您可能可以使用objc桥接,但代价是:您需要将协议和具体类型都标记为@objc,从而丢失所有swift特有的特性。我不完全相信它不会工作,但目前无法访问源代码。明天我就知道了!如果您感兴趣,请参阅我的上面的编辑…@StephenGroom请阅读更新的答案-添加了另一种方法-不太优雅,但它可能会解决您的问题这是我们上次看到这个问题时遇到的地方:D关于一个非常类似的问题的扩展讨论,请参见。在这种情况下,答案是传递可以构造所需内容的闭包。也就是说,在您的特定情况下,如果处理程序只是
createableclass
(而不是类的类型),那么它就可以工作了。所以我想问题还不止这些。
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() }