req*_*zix 8 type-inference objective-c ios swift swift-extensions
我正在尝试创建Fabric方法来创建具有正确nib名称的UIViewController(以修复iOS8默认初始化问题).要做到这一点,我添加了扩展名:
extension UIViewController {
class func create() -> Self {
if #available(iOS 9.0, *) {
return self.init()
} else {
let clsName = NSStringFromClass(self).componentsSeparatedByString(".").last!
return self.init(nibName: clsName, bundle: nil)
}
}
}
Run Code Online (Sandbox Code Playgroud)
但编译器发出错误:Cannot convert value of type 'Self.Type' to expected argument type 'AnyClass' (aka 'AnyObject.Type')in NSStringFromClass(self).
要修复它,可以添加另一个扩展方法并将代码重写为:
extension UIViewController {
private class var nibNameForInitializer:String {
return NSStringFromClass(self).componentsSeparatedByString(".").last!
}
class func create_() -> Self {
if #available(iOS 9.0, *) {
return self.init()
} else {
return self.init(nibName: self.nibNameForInitializer, bundle: nil)
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我想了解第一个变体的问题.
据我所知,返回方法Self是一种通用方法.Self可以在许多上下文中使用(例如类,结构,协议,等等),但是Self.Type匹配AnyClass只对类.
在我的例子中,编译器应该知道Self引用UIViewController它的所有子类(因为它在UIViewController扩展内),所以Self.Type必须可以转换为AnyClass.
我是否会遗漏任何内容,或者它是正确的行为,因为编译器不执行任何其他类型分析Self?
Mar*_*n R 11
这看起来像是一个错误或(不必要的)限制,因此您可以考虑在Apple上提交错误报告.它仅适用于具有返回类型的类型方法Self.作为一种解决方法,你可以写
let clsName = NSStringFromClass(self as! AnyClass).componentsSeparatedByString(".").last!
Run Code Online (Sandbox Code Playgroud)
编译并似乎按预期工作.
但是有一种更简单的方法可以获得相同的结果:
// Swift 2:
let clsName = String(self)
// Swift 3:
let clsName = String(describing: self)
Run Code Online (Sandbox Code Playgroud)
也许这是一个错误,尝试强制沮丧,这就是我必须让它工作的方式:
let clsName = NSStringFromClass(self as! AnyClass).componentsSeparatedByString(".").last!
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7969 次 |
| 最近记录: |