ASIHTTPRequest/ASIFormDataRequest - ссылка объекта запроса в блоках под ARC

Очень похоже на этот вопрос, я пытаюсь преобразовать проект, который использует ASIHTTPRequest и ASIFormDataRequest в ARC.

В моих классах контроллера я часто ссылаюсь и использую свойства объекта request в блоках завершения (смотря на код ответа, данные ответа и т.д.):

__block  ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:SOME_URL]];    
[request setCompletionBlock:^{   

    if([request responseStatusCode] == 200) ....etc

При преобразовании в ARC я получаю предупреждение:

Захват "запроса" сильно в этом блоке, вероятно, приведет к сохранить цикл

Каков правильный способ сделать это?

Еще один пользователь SO в предыдущем потоке, который просто добавляет __weak, может заставить запрос быть выпущенным до завершения блока, который, как я считаю, является истинным.

Как я могу правильно ссылаться на эти свойства в блоках завершения/отказа в ARC?

Ответ 1

(Я прочитал ваш комментарий к другому вопросу)

После реализации нескольких модулей с использованием ASIHTTPRequest я узнал, что лучший способ - сохранить ссылку strong на ваш объект запроса. В вашем случае вы можете:

self.request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:SOME_URL]];
__weak ASIFormDataRequest *weakRequest = self.request; // __block directive not needed since we only access the instance properties. 
[self.request setCompletionBlock:^{   

    if([weakRequest responseStatusCode] == 200)
    // ...

Таким образом, вы можете управлять self.request даже после запуска запроса (например, для отмены). Вы можете сделать self.request = nil;, когда будете готовы освободить свой запрос, возможно, в вашем блоке завершения или self.request методах очистки родительских объектов.

Update:

Если вы ориентируетесь на pre-iOS 5, тогда общая земля стоит: используйте __unsafe_unretained вместо __weak. Это нормально, потому что, глядя на ASIHTTPRequest.m, блоки nil выходят в dealloc() (т.е. Они не должны выполняться). Хотя я еще не тестировал это, поэтому не забудьте проверить работу с NSZombies.

Примечание:

Единственным безопасным способом отмены объекта ASIHTTPRequest является вызов его метода clearDelegatesAndCancel. Я был укушен некоторыми неприятными ошибками, когда я просто использовал простой cancel.

Ответ 2

Если вы ориентируетесь на версии iOS до 5.0, которые не включают поддержку weak:

__unsafe_unretained __block ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];

Ответ 3

Я нашел этот ответ полезным: fooobar.com/info/32946/...

В нем говорится использовать __unsafe_unretained, а также __block