我有一个打算返回符合PanelControllerProtocol
的类的类。我遇到的问题是获取anyClass对象并将其转换为T.
func classFromBundle<T: PanelControllerProtocol>(className: String) -> T {
let bundleClassString = classBundleAndName(className)
var anyClass : AnyClass = NSClassFromString(bundleClassString)
}
如果我试试这个:
var panelControllerType = anyClass as T
我明白了:
“无法从具体类型'AnyClass'转换为类型变量'T' 它与约束条件不匹配“。
尝试简单地返回anyClass
会给我一个错误:
'AnyClass'不能转换为'T'
尝试将我的方法名称更改为:
func classFromBundle<T where T: AnyClass, T: PanelControllerProtocol>(className: String) -> T
给出错误:
类型'T'约束为非协议类型'AnyClass'
此外,一旦我弄清楚如何返回正确的对象,我不知道如何调用该类。目前,调用上述方法如下:
classFromBundle("Test")
给出错误:
无法将表达式的类型'NSString'转换为'String'类型
答案 0 :(得分:0)
您可以使用以下代码:
var instance: AnyObject? = NSClassFromString(bundleClassString)
let actualClassInstance = instance as T
return actualClassInstance
但是,正如您可能猜到的,如果找不到类类型,则会生成运行时异常。
更好的解决方案是让您的函数返回一个可选的T
,并为NSClassFromString
帐户创建T
类的实例失败:
var actualClassInstance: T?
var instance: AnyObject? = NSClassFromString(bundleClassString)
if instance != nil {
actualClassInstance = instance as? T
}
return actualClassInstance
请注意NSClassFromString
,相应于文档:
返回:由aClassName命名的类对象,如果当前没有加载该名称的类,则返回nil。
返回错误的类型AnyObject!
,而应该是AnyObject?
要调用该函数,您只需要告诉编译器T
是什么 - 并且您可以通过从函数结果分配给的变量中推断类型来实现:
let concreteClass: ConcreteClass = classFromBundle("ConcreteClass")
^^^^^^^^^^^^^
This tells the compiler what T is
如果您使用的是代码的第二个(更安全)版本,那么您应该将变量声明为可选:
let concreteClass: ConcreteClass? = classFromBundle("ConcreteClass")