Это довольно сложная иерархия наследования, так что потерпите меня (я пытался упростить вещи, а не указать конкретный случай, который я использую, который еще более сложен): -
Допустим, я создаю подкласс UITextField
с именем TextField
, который является моим собственным расширенным текстовым полем общего назначения. Теперь, чтобы обеспечить эту расширенную функциональность, в методе init
для TextField
я установил super.delegate = self
, чтобы все методы делегата из UITextField
отправлялись в TextField
. TextField
реализует протокол UITextFieldDelegate
и получает эти методы-делегаты для выполнения чего-то интересного.
Однако, в свою очередь, я хочу сделать так, чтобы у TextField
был свой собственный делегат. Поэтому я создаю новый протокол с именем TextFieldDelegate
(обратите внимание на отсутствие UI
-prefix!) И даю TextField
ivar id<TextFieldDelegate> __weak delegate
с соответствующим свойством, чтобы другие классы могли получать методы делегата от TextField
.
Надеюсь, ты все еще со мной, потому что я пока не сделал ничего слишком сложного. Но давайте скажем, что теперь я создаю другой пользовательский подкласс TextField
, назовем его PasswordTextField
(в реальной жизни, вероятно, не нужно создавать подкласс просто для реализации функциональности пароля, но давайте предположим, что есть некоторые довольно сложные реализации, которые потребовали бы этого).
Давайте также предположим, что я хочу сделать так, чтобы PasswordTextField
(который, как TextField
имеет свойство делегата) мог отправлять расширенный набор методов делегата. Например, может быть, он может отправить метод passwordIsSecure
, который отправляется, когда пароль достигает требуемого уровня сложности. Теперь, поскольку это поведение, которое не встречается в обычном TextField
, я создаю новый протокол: PasswordTextFieldDelegate <TextFieldDelegate>
, который определяет новые методы делегата для PasswordTextField
, а наследует все отправленные методы делегата. TextField
.
Проблема в том, как мне реализовать это в PasswordTextField
? Вещи, которые не работают:
Наследование
Я не могу просто наследовать делегат от TextField
, потому что делегат TextField
соответствует только TextFieldDelegate
, а не PasswordTextFieldDelegate
, поэтому я не могу отправлять методы, подобные [delegate passwordIsSecure]
, потому что TextFieldDelegate
не имеет такой метод.
Переопределение ivar
Я мог бы попытаться объявить ивар в PasswordTextField
с именем делегата, но компилятор жалуется, что это дублирующее объявление, потому что, конечно, в суперклассе уже есть ивар с именем делегата, так что это тоже не работает *.
Изменение суперкласса
Я мог бы вернуться к классу TextField
и переопределить делегата для реализации TextFieldDelegate
и PasswordTextFieldDelegate
, но это кажется грязным и говорит TextField
, что он может отправлять PasswordTextFieldDelegate
методы, которые, конечно, это не может!
Я не пробовал этого, просто потому что он, кажется, нарушает все разумные правила кодирования в книге.
Таким образом, должен быть какой-то способ сделать это так, чтобы у подкласса класса мог быть свой собственный делегат, который является суб-делегатом делегата суперкласса, и чтобы все это прекрасно сочеталось, но я просто могу ' не понять это! Есть идеи?
(* В качестве дополнительной проблемы, я не понимаю, почему компилятор жалуется, когда PasswordTextField
объявляет «дубликат» делегата с именем ivar, но не жалуется, когда TextField
объявляет делегат с именем ivar, который предположительно является дубликат свойства UITextField
называется делегатом!)