ASIHTTPRequest, EXC_BAD_ACCESS, когато заявката приключи

Опитвам се да направя асинхронна заявка с ASIHTTPRequest, но имам някакъв проблем с получаването на известия, когато заявката е изпълнена.

-(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
}

Някакви улики?


person Vegar    schedule 29.01.2010    source източник


Отговори (3)


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

Можете да добавите [self retain] към doDownload и [self release] към - (void)requestFinished:(ASIHTTPRequest *)request, но се уверете (!), че [self release] не се обажда твърде често. Това също е възможно изтичане на памет, ако заявката никога не завърши. Би било най-добре да запазите класа си някъде другаде.

Можете също така да опитате да отстраните грешки с NSZombieEnabled, зададено на YES, за да намерите грешката.

person MrMage    schedule 29.01.2010
comment
Това изглежда е правилният отговор. Имам проблем с управлението през целия живот, който трябва да бъде решен. Сега създавам клас за изтегляне, извиквам метод и незабавно освобождавам. Трябва да внедря някаква система за обратно извикване, за да позволя на собственика на екземпляра за изтегляне да знае кога нещата са готови. Ще ми трябва това в крайна сметка по всякакъв начин, за да скрия изгледите на напредъка и да актуализирам данни и т.н. Благодаря. - person Vegar; 30.01.2010
comment
Как може да стане това, когато работите с ARC? Моля, вижте моята тема тук. - person dhrm; 02.12.2011
comment
Тош. @tomute е прав, името на селектора е requestFinished:, а не requestFinished, това е целият проблем. Няма нужда да си разбивате хубавата малка главичка за цикли през целия живот и запазвания и други неща. - person Elise van Looij; 29.12.2011

Следващият ред от кода ви изглежда грешен.

[request setDidFinishSelector:@selector(requestFinished)];

Методът requestFinished има аргумент (ASIHTTPRequest *).
Следователно трябва да добавите ":", когато задавате селектор, както следва.

[request setDidFinishSelector:@selector(requestFinished:)];
person tomute    schedule 29.01.2010
comment
Ще повярвам на думата ви ;-) Благодаря. - person Vegar; 30.01.2010

[низ за отговор на искане];

Проверете retainCount на заявката преди това повикване. Вероятно е равно на нула :) Ако е така - не трябва да забравяте да го запазите, когато го създавате в метода doDownload.

person alexandrmoroz    schedule 29.01.2010
comment
Не мога да проверя заявките retainCount в requestFinished, тъй като requestFinished никога не се извиква. - person Vegar; 29.01.2010