Работа с отсутствием замыканий в Objective-C - PullRequest
7 голосов
/ 22 марта 2010

Возможно, это просто тот факт, что я недавно использовал http://nodejs.org/, но отсутствие замыканий в Objective-C (iphone) было действительно трудно обойти.

Например, я создаю классы обслуживания. Каждый класс обслуживания может иметь несколько методов, каждый из которых выполняет свой URL-запрос. Я могу использовать шаблон делегата, но это означает, что мне нужно создавать новый сервис каждый раз, когда я хочу вызвать для него метод (потому что он должен хранить делегат и селектор для этого запроса, а вызовы новых методов перезаписывают их) ,

Еще более сложным для меня является тот факт, что я не могу легко хранить локальные переменные в области видимости для обратного вызова. Мне нужно хранить все, что я хочу отправить обратно делегату, в самом классе обслуживания, что затрудняет использование более одного метода в каждом классе.

Как вы, профессионалы, делаете это? Должен ли я просто перестать ныть и сделать это по-другому?

Ответы [ 3 ]

10 голосов
/ 22 марта 2010

Блоки , которые были недавно введены в Objective-C, включают замыкания. Единственная проблема в том, что вы не можете использовать их на iPhone. А вот и решение сторонних производителей, Вероятные блоки - они предоставляют эту возможность и на iPhone.

Обновление: образец проекта с использованием блоков на iPhone можно найти здесь .

7 голосов
/ 22 марта 2010

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

Для чего-то вроде класса обслуживания вы, вероятно, сделаете одноэлементное и уведомите заинтересованные стороны о завершении запроса на обслуживание посредством уведомления.

Не то, чтобы блоки не были интересным решением этой проблемы, просто я чувствовал, что вы должны знать, что есть альтернативы.

1 голос
/ 23 марта 2010

Я не профессионал, но я боролся с той же проблемой, поэтому вот лучшее, что у меня есть:

@interface MyCallback : NSObject
  id target;
  SEL action;
  id value1;
  id value2;
  ...
@end

Когда мне нужно вызвать что-то, что сообщит мне о завершении, я заполняю заданную цель и действие фактическим обратным вызовом (обычно «self» и метод) и добавляю другие значения, которые мне понадобятся позже, в value1..2..3 Вызываемый объект держится за объект MyCallback, а когда приходит время, он вызывает цель / действие и передает MyCallback в качестве параметра. Вот так я и получаю свое "закрытие".

Чтобы решить другую проблему, вот идея: создайте класс, производный от NSURLConnection, с именем MYURLConenction, и единственным дополнением является поле типа "id", назовите его MyStuff. Затем перейдите к использованию MYURLConenction вместо NSURLConnection - когда вы делаете сетевой запрос, вы можете вставить свои данные (например, экземпляр MyCallback) в MyStuff, и он будет зависеть от них за вас. Поэтому вам не нужно будет создавать новый экземпляр класса обслуживания для каждого вызова.

Хотя на самом деле это не то, как я это делаю - я просто создал универсальный класс-обертку MyHTTPRequest, являющийся делегатом NSURLConnection, он принимает тело URL-адреса и NSString POST, обрабатывает все содержимое сети и возвращает результат NSString и NSErrrrr для вызывающей стороны - чуть более высокая абстракция. Он также хранит MyStuff, так что классы обслуживания могут оставаться одиночными, если они этого хотят.

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