2010-01-29 4 views
3

Je suis en train de faire une demande asynchrone avec ASIHTTPRequest, mais ont quelques problèmes à se prévenir si la demande est faite.ASIHTTPRequest, EXC_BAD_ACCESS lorsque la demande avait fini

-(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 n'est jamais appelé. Je reçois une exception dans ASIHTTPRequest.m, -handleStreamCompleted:

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

Des indices?

Répondre

7

Etes-vous sûr que votre classe qui implémente - (void)requestFinished:(ASIHTTPRequest *)request est toujours là quand la demande se termine? Il me semble que la classe est désengagée trop tôt. Notez que la propriété delegate ne conserve pas son contenu.

Vous pouvez ajouter un [self retain] à doDownload et un [self release]-- (void)requestFinished:(ASIHTTPRequest *)request, mais assurez-vous (!) Que [self release] ne soit pas appelé trop souvent. C'est aussi une fuite de mémoire possible si une requête ne se termine jamais. Il serait préférable de conserver votre classe ailleurs.

Vous pouvez également essayer de déboguer avec NSZombieEnabled défini sur YES pour trouver l'erreur.

+0

Cela semble être la bonne réponse. J'ai un problème de gestion à vie qui doit être résolu. Maintenant, je crée une classe de téléchargement, appelle une méthode et la libère immédiatement. Je dois implémenter un système de rappel pour permettre au propriétaire de l'instance de téléchargement de savoir quand les choses sont faites. J'en aurais besoin éventuellement, pour masquer les vues de progression et mettre à jour les données, etc. Merci. – Vegar

+0

Comment cela peut-il être fait avec ARC? S'il vous plaît voir mon [sujet ici] (http://stackoverflow.com/questions/8355974). – dhrm

+0

Tosh. @tomute a raison, le nom du sélecteur est requestFinished :, requestFinished, c'est tout le problème. Pas besoin de casser votre jolie petite tête au cours des cycles de vie et conserve et d'autres choses. –

0

[demande responseString];

Vérifiez retainCount de la demande avant cet appel. Propably, il est égal à zéro :) Si cela - vous ne devriez pas oublier de le conserver lorsque vous le créez en méthode doDownload.

+0

Je ne peux pas vérifier les demandes retainCount dans requestFinished, car requestFinished n'est jamais appelé. – Vegar

4

Après la ligne de votre code semble erroné.

[request setDidFinishSelector:@selector(requestFinished)]; 

requestFinished procédé a un argument (ASIHTTPRequest *).
Par conséquent, vous devez ajouter « : », lorsque vous définissez un sélecteur comme la manière suivante.

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

Je vais vous croire sur parole ;-) Merci. – Vegar