Перезвонить стиль - PullRequest
1 голос
/ 04 мая 2009

Я пишу приложение для iPhone, которое во многих местах должно выполнять не HTTP или FTP сеть очень простого типа ответа на запрос.

Я обернул все это в класс SimpleQuery, который интегрируется с циклом выполнения.

SimpleQuery *lookup = [[SimpleQuery alloc] init];
[lookup setDelegate:self];
[lookup doQueryToHost:queryServer port:queryPort query:queryString ];   

Как видите, вызывающий объект устанавливает себя в качестве делегата. Когда результаты завершены, он вызывает метод для делегата с результатами.

[delegate simpleQueryResult:resultString simpleQuery:self];             

Сейчас я нахожусь в состоянии, когда у меня есть пользователь SimpleQuery, у которого есть два типа запросов, поэтому мне нужно расширить SimpleQuery для поддержки этого.

Я могу придумать два разумных способа сделать это.

Сначала передается селектор в doQueryString или отдельный doQueryStringWithSelector.

[lookup doQueryToHost:queryServer port:queryPort query:queryString selector:@SEL ]; 

Во-вторых, передача тега в doQueryString, чтобы при вызове делегата он мог запросить тег при передаче simpleQuery, чтобы выяснить, для чего нужны результаты.

[lookup doQueryToHost:queryServer port:queryPort query:queryString withTag:tag ];

Мне просто интересно, какой из них лучше с точки зрения стиля кодирования, первый кажется проще, но тегирование кажется более подходящим для iPhone SDK и Interface Builder

Ответы [ 3 ]

2 голосов
/ 05 мая 2009

Опция, которая обычно используется в коде Apple (например, в UIControl), заключается в предоставлении как целевого объекта, так и селектора. Это работает только при наличии одного обратного вызова и в этом случае более подходит, чем делегат. (Если существует несколько обратных вызовов, вам, вероятно, придется использовать делегат и подход с использованием тегов.)

Если вы пойдете по этому пути, тогда вы полностью покончите с делегатом и вместо этого получите метод с такой подписью:

doQueryToHost:(id)queryServer port:(int)queryPort query:(NSString*)queryString target:(id)target action:(SEL)action

Обратите внимание, что в этом случае «action» обычно предпочтительнее «селектора» в аргументах методов. Запрос просто вызовет селектор на цели, когда закончите. Это позволит вашим клиентам иметь несколько селекторов, а также несколько целевых объектов; это может помочь очистить код, потому что вам не нужно объединять все в один объект делегата.

Если вы хотите использовать свой маршрут тега, вы должны назвать его «context», который Apple использует (например, в addObserver: forKeyPath: options: context).

1 голос
/ 05 мая 2009

Я не уверен, что понимаю проблему здесь. Разве пользователь SimpleQuery не может просто установить другой объект делегата для второго запроса или ветвь для параметра simpleQuery:? Это базовая часть шаблона делегата, аналогично наличию двух UIActionSheets для одного контроллера представления.

1 голос
/ 05 мая 2009

Существует третий вариант, который является общим шаблоном в наборах, который должен использовать @protocol s.

Например:

@protocol QueryCompleteHandlerProtocol
- (void)queryType1Complete:(int)intStuff;
- (void)queryType2Complete:(float)floatStuff;
@end

То, что это делает, это объявляет набор вызовов методов, которым должен соответствовать объект, принимающий протокол (компилятор будет фактически обеспечивать это).

Таким образом, ваш объект SimpleQuery будет удерживать что-то вроде указателя делегата, который вы можете объявить следующим образом среди ivars:

NSObject<QueryCompleteHandlerProtocol> *callback;

То, что это говорит компилятору, это то, что callback является объектом, который происходит от NSObject и принимает протокол QueryCompleteHandlerProtocol. Иногда вы видите это в виде:

id<QueryCompleteHandlerProtocol> callback;

Когда вы хотите вызвать обратный вызов, в них нет ничего особенного, методы SimpleQuery просто вызовут:

[callback queryType1Complete:1];
[callback queryType2Complete:2.0];

Наконец, ваш клиент для класса procotol объявит себя принимающим протокол:

@interface MyClass : NSObject<QueryCompleteHandlerProtocol>
...
@end

И будет настроен как обратный вызов с некоторым кодом, например:

[lookup setCallback:self];

Здесь компилятор проверяет, что MyClass соответствует QueryCompleteHandlerProtocol, что означает, что он реализовал queryType1Complete: и queryType2Complete:.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...