Chi*_*buZ 35 swift swift-extensions swift2
我正在尝试进行此扩展:
extension UIViewController
{
class func initialize(storyboardName: String, storyboardId: String) -> Self
{
let storyboad = UIStoryboard(name: storyboardName, bundle: nil)
let controller = storyboad.instantiateViewControllerWithIdentifier(storyboardId) as! Self
return controller
}
}
Run Code Online (Sandbox Code Playgroud)
但我得到编译错误:
错误:无法将'UIViewController'类型的返回表达式转换为返回类型'Self'
可能吗?我也想成为init(storyboardName: String, storyboardId: String)
Mar*_*n R 66
类似于在Swift中的类扩展函数中使用'self',您可以定义一个通用的辅助方法,它从调用上下文中推断出self的类型:
extension UIViewController
{
class func instantiateFromStoryboard(storyboardName: String, storyboardId: String) -> Self
{
return instantiateFromStoryboardHelper(storyboardName, storyboardId: storyboardId)
}
private class func instantiateFromStoryboardHelper<T>(storyboardName: String, storyboardId: String) -> T
{
let storyboard = UIStoryboard(name: storyboardName, bundle: nil)
let controller = storyboard.instantiateViewControllerWithIdentifier(storyboardId) as! T
return controller
}
}
Run Code Online (Sandbox Code Playgroud)
然后
let vc = MyViewController.instantiateFromStoryboard("name", storyboardId: "id")
Run Code Online (Sandbox Code Playgroud)
编译,类型推断为MyViewController.
Swift 3更新:
extension UIViewController
{
class func instantiateFromStoryboard(storyboardName: String, storyboardId: String) -> Self
{
return instantiateFromStoryboardHelper(storyboardName: storyboardName, storyboardId: storyboardId)
}
private class func instantiateFromStoryboardHelper<T>(storyboardName: String, storyboardId: String) -> T
{
let storyboard = UIStoryboard(name: storyboardName, bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: storyboardId) as! T
return controller
}
}
Run Code Online (Sandbox Code Playgroud)
另一种可能的解决方案,使用unsafeDowncast:
extension UIViewController
{
class func instantiateFromStoryboard(storyboardName: String, storyboardId: String) -> Self
{
let storyboard = UIStoryboard(name: storyboardName, bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: storyboardId)
return unsafeDowncast(controller, to: self)
}
}
Run Code Online (Sandbox Code Playgroud)
Rob*_*ier 15
Self是在编译时确定的,而不是运行时.在你的代码中,Self完全等同于UIViewController,而不是"恰好调用它的子类".这将返回UIViewController,调用者必须将as它放入正确的子类中.我认为这是你试图避免的(虽然这是"正常的可可"方式,所以只返回UIViewController可能是最好的解决方案).
注意:initialize在任何情况下都不应该命名该函数.这是现有的类函数,NSObject并且最多会引起混淆,最坏的情况是错误.
但是如果你想避免调用者的话as,子类化通常不是在Swift中添加功能的工具.相反,您通常需要泛型和协议.在这种情况下,您只需要泛型.
func instantiateViewController<VC: UIViewController>(storyboardName: String, storyboardId: String) -> VC {
let storyboad = UIStoryboard(name name: storyboardName, bundle: nil)
let controller = storyboad.instantiateViewControllerWithIdentifier(storyboardId) as! VC
return controller
}
Run Code Online (Sandbox Code Playgroud)
这不是一种类方法.这只是一个功能.这里没有必要上课.
let tvc: UITableViewController = instantiateViewController(name: name, storyboardId: storyboardId)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12481 次 |
| 最近记录: |