如何在指定的初始值设定项中调用协议扩展初始值设定项?

杜鲁门1

我正在尝试将协议扩展初始化程序注入到现有类的指定初始化程序中。我认为没有办法避免从类中覆盖指定的初始化程序,然后在其中调用协议扩展初始化程序。

以下是我正在尝试的内容,特别是在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。另外,您已经将MyProtocolsetupLocationManager注入了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.
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章