Я хотел бы динамически присоединить замыкание к другому методу из init класса. Например, для UIViewController
я хотел бы добавить расширение, чтобы я мог ввести код в событие viewDidLoad
. Я пытался что-то вроде ниже, но это не работает:Можно ли динамически подключать логику к методу?
class BaseViewController: UIViewController, MyProtocol {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
// Setup and bind
configure()
}
override func viewDidLoad() {
super.viewDidLoad()
// Call MyProtocol.myDidLoad but not explicitly!
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
// Call viewWillAppear but not explicitly!
}
}
protocol MyProtocol { }
extension MyProtocol where Self: UIViewController {
func configure() {
// Something like below isn't possible???
self.viewDidLoad += myDidLoad
self.viewWillAppear += myWillAppear
}
func myDidLoad() {
// Something
}
func myWillAppear() {
// Something
}
}
ли достижение этой цели возможно, без явного вызова функции протокола из UIViewController
? Я не хочу проходить все классы и вызывать функции протокола для каждой функции. Это было бы утомительным, избыточным кодом, и его можно легко упустить. Есть ли более элегантный способ?
UPDATE:
Ниже единственный способ, которым я могу думать, учитывая ограничения, но с использованием наследования над составом и еще требуя, чтобы я явно вызывать функции расширения протокола, который не является что я хочу делать:
class FirstViewController: BaseViewController {
}
class BaseViewController: UIViewController, MyProtocol, MyProtocol2, MyProtocol3 {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
// Configure protocols
configure(self as MyProtocol)
configure(self as MyProtocol2)
configure(self as MyProtocol3)
}
override func viewDidLoad() {
super.viewDidLoad()
// Load protocols
viewDidLoad(self as MyProtocol)
viewDidLoad(self as MyProtocol2)
viewDidLoad(self as MyProtocol3)
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
// Prerender protocols
viewWillAppear(self as MyProtocol)
viewWillAppear(self as MyProtocol2)
viewWillAppear(self as MyProtocol3)
}
}
protocol MyProtocol { }
extension MyProtocol where Self: UIViewController {
func configure(delegate: MyProtocol) {
print("MyProtocol.configure")
}
func viewDidLoad(delegate: MyProtocol) {
print("MyProtocol.viewDidLoad")
}
func viewWillAppear(delegate: MyProtocol) {
print("MyProtocol.viewWillAppear")
}
}
protocol MyProtocol2 { }
extension MyProtocol2 where Self: UIViewController {
func configure(delegate: MyProtocol2) {
print("MyProtocol2.configure")
}
func viewDidLoad(delegate: MyProtocol2) {
print("MyProtocol2.viewDidLoad")
}
func viewWillAppear(delegate: MyProtocol2) {
print("MyProtocol2.viewWillAppear")
}
}
protocol MyProtocol3 { }
extension MyProtocol3 where Self: UIViewController {
func configure(delegate: MyProtocol3) {
print("MyProtocol3.configure")
}
func viewDidLoad(delegate: MyProtocol3) {
print("MyProtocol3.viewDidLoad")
}
func viewWillAppear(delegate: MyProtocol3) {
print("MyProtocol3.viewWillAppear")
}
}
//Output:
//MyProtocol.configure
//MyProtocol2.configure
//MyProtocol3.configure
//MyProtocol.viewDidLoad
//MyProtocol2.viewDidLoad
//MyProtocol3.viewDidLoad
//MyProtocol.viewWillAppear
//MyProtocol2.viewWillAppear
//MyProtocol3.viewWillAppear
Это побеждает всю цель протокола ориентированного программирования. Есть ли элегантный подход, который Swift может обрабатывать при работе в рамках разработки iOS, или POP не работает в этом случае?
Я сделал то, что вы предлагали, и обновил ответ с помощью нового кода, он очень утомительный и не очень элегантный. Я думаю, что POP не был создан для разработки iOS? – TruMan1
Я думаю, что в то время как POP предоставляет некоторые функции множественного наследования, это не то же самое, что множественное наследование. Swift и Objective-C являются как единичными языками наследования. Протоколы обеспечивают много преимуществ множественного наследования, но избегают проблемы с алмазами - https://en.wikipedia.org/wiki/Multiple_inheritance. Даже эти языки с множественным наследованием требуют, чтобы вы решительно решали проблему с алмазом и поэтому не разрешали выполнение всех ваших реализаций 'viewDidLoad' – Paulw11