如何在指定初始化器中调用协议扩展初始化器?
How to call protocol extensions initializers in designated initializers?
我正在尝试将协议扩展初始化程序注入现有 class 的指定初始化程序。我不认为有什么办法可以解决这个问题,除非覆盖 class 中的指定初始化程序,然后在其中调用协议扩展初始化程序。
下面是我正在尝试的,特别是 UIViewController
class:
class FirstViewController: UIViewController, MyProtocol {
var locationManager: CLLocationManager?
var lastRendered: NSDate?
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
// TODO: How to call MyProtocol initializer?
// (self as MyProtocol).init(aDecoder) // Didn't compile
}
}
protocol MyProtocol: CLLocationManagerDelegate {
var locationManager: CLLocationManager? { get set }
var lastRendered: NSDate? { get set }
init?(coder aDecoder: NSCoder)
}
extension MyProtocol where Self: UIViewController {
// Possible to inject this into initialization process?
init?(coder aDecoder: NSCoder) {
self.init(coder: aDecoder)
setupLocationManager()
}
func setupLocationManager() {
locationManager = CLLocationManager()
locationManager?.delegate = self
locationManager?.desiredAccuracy = kCLLocationAccuracyThreeKilometers
locationManager?.distanceFilter = 1000.0
locationManager?.startUpdatingLocation()
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
// TODO
}
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
// TODO
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
// TODO
}
}
有没有办法利用协议扩展初始化程序,以便在框架的现有初始化过程中自动调用它?
您不需要调用不同的初始化程序;你已经在初始化了。此外,您不需要将 self
转换为 MyProtocol;您已经声明它采用 MyProtocol。另外,你已经将 MyProtocol 的 setupLocationManager
注入到 FirstViewController 中,因为你的 FirstViewController 已经采用了 MyProtocol 并且 MyProtocol 上的扩展针对的是 UIViewController,FirstViewController 的超类。
所以,这个方法已经被注入了;现在就直接在初始化程序中调用注入的方法,您已经 运行。您的代码的以下精简版本编译得非常好:
class FirstViewController: UIViewController, MyProtocol {
var locationManager: CLLocationManager?
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.setupLocationManager() // no problem!
}
}
protocol MyProtocol: CLLocationManagerDelegate {
// this next line is necessary so that
// ...setupLocationManager can refer to `self.locationManager`
var locationManager: CLLocationManager? { get set }
}
extension MyProtocol where Self: UIViewController {
func setupLocationManager() {
locationManager = CLLocationManager()
// ... etc.
}
// ... etc.
}