ASIHTTPRequest / ASIFormDataRequest - ссылка на объект запроса в блоках под ARC - PullRequest
21 голосов
/ 14 января 2012

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

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

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

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

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

Сильный захват 'request' в этом блоке может привести к сохранить цикл

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

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

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

Ответы [ 3 ]

27 голосов
/ 16 января 2012

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

После реализации еще нескольких модулей с использованием 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's properties. 
[self.request setCompletionBlock:^{   

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

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

Обновление:

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

Примечание:

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

2 голосов
/ 15 января 2012

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

__unsafe_unretained __block ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
1 голос
/ 20 января 2012

Я нашел этот ответ полезным: https://stackoverflow.com/a/7735770/133875

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

...