Частые ошибки с делегацией в Какао
Q: Один из методов делегата в моем приложении Какао не вызывается. Что является, вероятно, неправильным?
A: Один из методов делегата в моем приложении Какао не вызывается. Что является, вероятно, неправильным?
Когда сообщение делегата не получается, как Вы предназначили, это обычно - знак одной из двух вещей, также:
селекторы метода не соответствуют, часто из-за capitialization или недостающего двоеточия, или
выход делегата не был установлен или просто установлен в неправильный объект.
Проиллюстрировать далее, скажем, что Вы хотите обработать попытки пользователя закрыть окно myWindow в Вашем приложении. Когда пользователь щелкнет по рамке для закрытия, объект окна отправит эквивалент [delegate respondsToSelector:@selector(windowShouldClose:)] видеть, должно ли это даже отправить сообщение делегата. Если получатель nil, или respondsToSelector: тестовые возвраты NO, сообщение делегата не будет отправлено.
Проверьте, что соответствуют сигнатуры методов
Убедитесь, что Вы реализовали правильный метод. Это весьма характерно для селектора метода как -windowShouldClose: любому быть написанным c орфографическими ошибками (например, -windowShoulfClose:), miscapitalized (например, -windowShouldclose:) или пропускать двоеточие (-windowShouldClose). Они все описывают различный метод, и тест во время выполнения перестанет работать.
Возможно, самая безопасная привычка разработать состоит в том, чтобы просто всегда вырезать и вставлять селектор метода. В более ранних выпусках Mac OS X можно найти методы делегата на странице Class Reference. В более свежих выпусках Вы также найдете, что методы делегата группировались как неофициальный протокол (категория на NSObject). Например, методы делегата окна объявляются в NSWindow.h в NSObject(NSWindowDelegate) категория.
Гарантируйте, что делегат установлен должным образом
Даже при реализации корректного метода может быть просто пропустить присвоение объекта делегата. Иногда соединение, возможно, стало разъединенным в файле пера или быть сделанным к неправильному объекту. Так обязательно проверьте и удостоверьтесь что переменная экземпляра (чаще всего IBOutlet именованный delegate) соединяется правильно в Интерфейсном Разработчике, или альтернативно, что надлежащий метод доступа используется для установки переменной экземпляра во время выполнения.
Перечисление 1 , Если Вы не делаете или не можете, присваивает делегата в Интерфейсном Разработчике, можно установить его в коде.
- (void) awakeFromNib { [[NSFontManager sharedManager] setDelegate:self]; } |
До выпуска полагайте, что использование утверждений гарантирует, что соединения были установлены правильно.
Использование перечисления 2 NSAssert () во время отладки для тестирования на соединение делегата.
#if ! defined(NDEBUG)
- (void) awakeFromNib {
// let's make sure that connection in Interface Builder was made, and made to us
NSAssert([myWindow delegate] == self, @"You forgot to connect the window delegate.!");
// ...
}
#endif |
Делегаты и управление памятью
Обратите внимание на то, что делегирующие объекты сохраняют слабую ссылку на своих делегатов. Другими словами, делегаты не сохраняются объектами, на которые они отвечают: они свободны прийти и уйти в любое время. При использовании сборки «мусора» эта слабая ссылка означает, что Вы ничего не должны делать об этом отношении, когда забран делегат. Однако при использовании сохраняют подсчет, важно явно очистить это отношение, когда освобожден объект.
Перечисление 3 Если не при сборке «мусора», делегат должен очистить себя перед освобождением.
- (void) dealloc { // unhook ourselves so the window won't try to message us in the future [myWindow setDelegate:nil]; [super dealloc]; } |
Для получения дополнительной информации
См. документацию Какао для больше на Делегатах и Источниках данных.
История версии документа
| Дата | Примечания |
|---|---|
| 27.02.2008 | Новый документ, что две наиболее распространенных ошибки, приводящие к методу делегата, не получаемому. |