我正在编写方法,它采用符合协议的类型并实例化此类的实例。当我构建它时,编译器崩溃了一个段错误。我很欣赏这一点在99%的情况下指向编译器错误,但是我有兴趣看看我尝试做的事情在逻辑上是否正确,或者我只是在编译器中抛出绝对的废话,我不应该'看到它崩溃会感到惊讶。
这是我的代码
protocol CreatableClass {
init()
}
class ExampleClass : CreatableClass {
required init() {
}
}
class ClassCreator {
class func createClass(classType: CreatableClass.Type) -> CreatableClass {
return classType()
}
}
ClassCreator.createClass(ExampleClass.self)
我还试图排除将Type作为方法参数传递为问题的根源,以下代码也会使编译器崩溃:
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 :(得分: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兼容的类,但是它不能满足我的需求......