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 
    } 
} 

Есть ли способ, чтобы использовать расширение протокола инициализаторов так он вызывается автоматически при существующем процессе инициализации фреймворки?

ответ

0

Вам не нужно для вызова другого инициализатора; вы уже инициализируетесь. Кроме того, вам не нужно вводить self в MyProtocol; вы уже заявили, что он принимает MyProtocol. Кроме того, вы уже ввели MyView Protector 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. 
}