Swift 如何在指定的初始值设定项中调用协议扩展初始值设定项?
我试图将协议扩展初始值设定项注入现有类的指定初始值设定项中。我认为如果不重写类中指定的初始值设定项,然后在类中调用协议扩展初始值设定项,就没有办法解决这个问题 下面是我正在尝试的,特别是使用Swift 如何在指定的初始值设定项中调用协议扩展初始值设定项?,swift,class,swift2,designated-initializer,protocol-extension,Swift,Class,Swift2,Designated Initializer,Protocol Extension,我试图将协议扩展初始值设定项注入现有类的指定初始值设定项中。我认为如果不重写类中指定的初始值设定项,然后在类中调用协议扩展初始值设定项,就没有办法解决这个问题 下面是我正在尝试的,特别是使用UIViewController类: class FirstViewController: UIViewController, MyProtocol { var locationManager: CLLocationManager? var lastRendered: NSDate?
UIViewController
类:
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.
}