Делегировать как внешний класс в Objective-C - PullRequest
3 голосов
/ 20 января 2009

Я создаю простой проект для iPhone, используя Xcode и Interface Builder. Хотя я понимаю, что такое делегат, у меня есть проблема с его использованием.

В моем интерфейсе есть UITextField. Он отображает клавиатуру, когда пользователь нажимает на нее, но мне нужно вручную запрограммировать, как скрыть клавиатуру. Это можно сделать с помощью делегатов. Поэтому в IB я беру Object из библиотеки, присваиваю его имя класса как Control1Delegate, а затем подключаю выход делегата из моего текстового поля к этому Control1Delegate. У меня также есть файлы .m и .h для этого класса Control1Delegate:

Control1Delegate.h

@interface Control1Delegate : NSObject <UITextFieldDelegate> {
}

- (BOOL) textFieldShouldReturn:(UITextField *)textField;

@end

Control1Delegate.m

#import "Control1Delegate.h"

@implementation Control1Delegate

- (BOOL) textFieldShouldReturn:(UITextField *)textField {
    [textField resignFirstResponder];
    return YES;
}

@end

Но это не работает. При запуске он просто не достигает метода textFieldShouldReturn или падает без сообщения msg или EXEC_BAD_ACCESS. Самое смешное, что когда я перемещаю метод в файл контроллера (сгенерированный одним мастером) и подключаюсь из UITextField к этому контроллеру (владельцу файла), все работает как положено. Я видел, что в большинстве руководств по написанию кода Apple делегированные методы помещаются в случайные объекты, а не в отдельный класс - я хотел бы знать, почему. Разве я не могу иметь делегата в отдельном классе?

Что мне здесь не хватает? Какой-нибудь нулевой указатель? Объект живого цикла?

Ответы [ 3 ]

1 голос
/ 20 января 2009

Ваш объект Control1Delegate разрушается вскоре после его создания. Все объекты Nib верхнего уровня должны быть сохранены, если вы хотите сохранить их живыми. См. Руководство по программированию ресурсов: жизненный цикл пера .

Владелец файла может иметь такое свойство, чтобы сохранить объект:

@property (nonatomic, retain) IBOutlet Control1Delegate *control1delegate;

Не забудьте освободить объект после того, как он больше не нужен.

0 голосов
/ 20 января 2009

Спасибо вам обоим. Теперь я не только знаю, как решить мою проблему, но и наконец понял, как объекты сохраняются в процессе создания Nib. Недостаточно создать объект в IB, если это новый объект, он должен быть подключен к реальному ивару в File's Owner (с правильно синтезированным getter / setter).

0 голосов
/ 20 января 2009

Вы можете поместить методы делегата в любой класс, включая один, созданный специально для этой цели. Причина, по которой Apple (и другие программисты) обычно не создают классы специально для функций делегатов, заключается в том, что они становятся слишком сложными и трудными для обмена данными. Например, в одном из моих проектов я мог бы создать подкласс Window Controller, который обрабатывает методы делегирования из окна, табличного представления внутри окна и панели инструментов окна. Все, что вам нужно для управления и поддержания состояния этого окна, находится в одном классе контроллера. Теперь представьте, что три отдельных класса (плюс, вероятно, класс контроллера для управления ими) выполняют одни и те же функции - это большая дополнительная работа без реальной выгоды.

Что касается причины сбоя, похоже, вы ошиблись с управлением памятью где-то еще в вашем приложении. Вы можете использовать отладчик, чтобы отследить, откуда он.

...