【问题标题】:How to call protocol extensions initializers in designated initializers?如何在指定的初始化程序中调用协议扩展初始化程序?
【发布时间】:2016-02-21 19:36:41
【问题描述】:

我正在尝试将协议扩展初始化程序注入现有类的指定初始化程序。如果不覆盖类中指定的初始化程序,然后在其中调用协议扩展初始化程序,我认为没有办法解决它。

以下是我正在尝试的,特别是 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
    }
}

有没有办法利用协议扩展初始化器,以便在框架现有的初始化过程中自动调用它?

【问题讨论】:

    标签: swift class swift2 designated-initializer protocol-extension


    【解决方案1】:

    您不需要调用不同的初始化程序;你已经在初始化了。此外,您不需要将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.
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-06
      • 2015-09-12
      • 1970-01-01
      • 1970-01-01
      • 2011-07-11
      • 1970-01-01
      相关资源
      最近更新 更多