2010-01-29 2 views
3

Я пытаюсь выполнить асинхронный запрос с ASIHTTPRequest, но есть некоторые проблемы с уведомлением о том, когда запрос выполнен.ASIHTTPRequest, EXC_BAD_ACCESS, когда запрос завершен

-(void)doDownload{ 
    NSURL *url = [NSURL URLWithString:@"http://www.someurl.com/?"]; 
    ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url]; 
    [request setPostValue:@"someValue" forKey:@"someField"]; 
    [request setRequestMethod:@"POST"]; 

    [request setDelegate:self]; 
    [request setDidFinishSelector:@selector(requestFinished)]; 
    [request startAsynchronous]; 
} 

- (void)requestFinished:(ASIHTTPRequest *)request 
{ 
    // Use when fetching text data 
    NSString *responseString = [request responseString]; 

} 

requestFinished никогда не вызывается. Я получаю исключение в ASIHTTPRequest.m, -handleStreamCompleted:

if (fileError) { 
    [self failWithError:fileError]; 
} else { 
    [self requestFinished]; <----- this call fails 
} 

Есть улики?

ответ

7

Вы уверены, что ваш класс, который реализует - (void)requestFinished:(ASIHTTPRequest *)request, все еще существует, когда запрос заканчивается? Мне кажется, что класс освобождается слишком рано. Обратите внимание, что свойство delegate не сохраняет свое содержание.

Вы можете добавить [self retain] к doDownload и [self release] к - (void)requestFinished:(ASIHTTPRequest *)request, но убедитесь, что (!), Что [self release] не дозвонились слишком часто. Это также возможная утечка памяти, если запрос никогда не завершится. Было бы лучше сохранить ваш класс где-то в другом месте.

Вы также можете попробовать отладить с помощью NSZombieEnabled значение YES, чтобы найти ошибку.

+0

Это, кажется, правильный ответ. У меня есть проблема управления жизненным циклом, которая нуждается в решении. Теперь я создаю класс загрузки, вызываю метод и сразу же выпускаю. Я должен реализовать некоторую систему обратного вызова, чтобы позволить владельцу экземпляра загрузки знать, когда все будет сделано. Мне это нужно в любом случае, чтобы скрывать представления прогресса и обновлять данные и т. Д. Спасибо. – Vegar

+0

Как это можно сделать при работе с ARC? См. Мою [тему здесь] (http://stackoverflow.com/questions/8355974). – dhrm

+0

Tosh. @tomute прав, имя селектора requestFinished :, not requestFinished, вот и вся проблема. Не нужно ломать свою симпатичную маленькую голову на протяжении жизненных циклов и сохраняет и прочее. –

0

[запрос responseString];

Перед тем, как звонить, проверьте удержание запроса. Упрощенно оно равно нулю :) Если это - вы не должны забывать его сохранять, когда вы его создаете в doDownload метод.

+0

Я не могу проверить запросы keepCount in requestFinished, так как requestFinished никогда не вызывается. – Vegar

4

Следующая строка вашего кода кажется неправильной.

[request setDidFinishSelector:@selector(requestFinished)]; 

requestFinished метод имеет аргумент (ASIHTTPRequest *).
Поэтому вы должны добавить ":", когда вы установите селектор следующим образом.

[request setDidFinishSelector:@selector(requestFinished:)]; 
+0

Пользуюсь твоим словом ;-) Спасибо. – Vegar