Протоколно-ориентированное расширение модуля init дважды
Здесь ситуация. У меня есть протокол и его расширение.
protocol CustomViewAddable {
var aView: UIView { get }
var bView: UIView { get }
func setupCustomView()
}
extension CustomViewAddable where Self: UIViewController {
var aView: UIView {
let _aView = UIView()
_aView.frame = self.view.bounds
_aView.backgroundColor = .grey
// this is for me to observe how many times this aView init.
print("aView: \(_aView)")
return _aView
}
var bView: UIView {
let _bView = UIView(frame: CGRect(x: 30, y: 30, width: 30, height: 30))
_bView.backgroundColor = .yellow
return _bView
}
func setupCustomView() {
view.addSubview(aView);
aView.addSubview(bView);
}
}
И я делаю ViewController для соответствия этому протоколу, а затем добавляю этот пользовательский "a View" в представление моего ViewController.
class MyVC: UIViewController, CustomViewAddable {
override func viewDidLoad() {
super.viewDidLoad()
setupCustomView()
}
}
Я запускаю это. В моем журнале консоли он печатает дважды init, и я пытался что-то сделать в моем собственном "a View", и это не удалось. (Код, который я вставил выше, я упростил, так что мне будет очень легко показать мое намерение)
Может ли кто-нибудь объяснить, почему или исправить это, что я буду очень признателен.
2 ответа
Потому что ваш var aView: UIView
вычисляемая переменная, а не переменная магазина,
Поэтому каждый раз, когда вы звоните aView
создаст новый UIView
,
Ты можешь использовать Associated Objects
в NSObject
вот несколько уроков:
Надеюсь, что это может помочь.
В основном в том, как вы реализовали setupCustomView
Метод ничего не должен работать, потому что, как упоминалось в другом ответе, вы используете вычисляемое свойство, так что это означает, что каждый раз, когда вы обращаетесь к свойству, оно создается снова.
Вам не нужно использовать связанные объекты или что-то в этом роде для достижения того, чего вы хотите, вам нужно только сохранить ссылку на aView
в начале, избегая повторного вызова, таким образом:
func setupCustomView() {
let tView = aView // only is computed once
view.addSubview(tView)
tView.addSubview(bView)
}
Я надеюсь, что это поможет вам.