2010-02-17 4 views
3

Ce morceau de code:Quel est le problème avec ce code de threads Objective-C pour mon application iPhone?

- (IBAction) getXML { 
    goButton.enabled = NO; 
    [self performSelectorInBackground:@selector(parseInBackground) withObject:nil]; 
} 

- (void)parseInBackground { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    xmlParser = [[XMLParser alloc] init]; 
    NSURL *xmlurl = [[NSURL alloc] initWithString:@"http://www.mysite.com/myfile.xml"]; 
    [xmlParser fetchXMLFromURL:xmlurl]; 
    [self performSelectorOnMainThread:@selector(didFinishXMLParsing) withObject:nil waitUntilDone:YES]; 
    [xmlurl release]; 
    [pool drain]; 
} 

- (void)didFinishXMLParsing { 
    goButton.enabled = YES; 
} 

déclenche ce code:

- (void)fetchXMLFromURL:(NSURL *)xmlurl { 
    XMLData = [[NSMutableData alloc] init]; 

    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:xmlurl]; 

    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; 
    [connection release]; 
    [request release]; 

    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES]; 
} 

Cependant, quand je fais un pas à travers elle dans le débogage, dès qu'il arrive à « } » en fetchXMLFromURL il retourne à la ligne:

[self performSelectorOnMainThread:@selector(didFinishXMLParsing) withObject:nil waitUntilDone:YES];

et la connexion à l'URL qui va chercher le code XML ne fait est déclenché. Quelqu'un a une idée pourquoi?


Cette version révisée semble fonctionner correctement, quelqu'un peut-il détecter des problèmes potentiels?

- (void)fetchXMLFromURL:(NSURL *)xmlurl { 
    XMLData = [[NSMutableData alloc] init]; 

    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES]; 
    XMLData = [NSData dataWithContentsOfURL:xmlurl]; 
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; 

    [self startParsingXML]; 
} 

- (void) startParsingXML 
{ 
    NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:XMLData]; 
    xmlParser.delegate = self; 
    [xmlParser parse]; 
    [xmlParser release]; 
} 

a de nouveau révisé, espérons corriger maintenant

- (void)fetchXMLFromURL:(NSURL *)xmlurl { 

    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES]; 
    XMLData = [[NSData alloc] initWithContentsOfURL:xmlurl]; 
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; 

    [self startParsingXML]; 
} 

- (void) startParsingXML 
{ 
    NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:XMLData]; 
    xmlParser.delegate = self; 
    [xmlParser parse]; 
    [xmlParser release]; 
} 

Répondre

4

Yep. La méthode NSURLConnection que vous utilisez est asynchrone elle-même: elle rappelle plusieurs méthodes de délégation différentes (comme indiqué par le protocole NSURLConnectionDelegate) lors de l'obtention de données. Vous pouvez, dans ce cas, utiliser la méthode +sendSynchronousRequest:returningResponse:error:, ou +dataWithContentsOfURL:options:error:, car tous les deux bloqueront l'exécution sur votre thread d'arrière-plan (ce qui est bien) jusqu'à ce qu'ils aient fini d'obtenir vos données. Assurez-vous également de définir la visibilité de l'indicateur d'activité réseau avant de lancer une requête synchrone.

+0

@Noah Witherspoon Donc, dans le cas d'origine, nous arrivons à la fin de 'fetchXMLFromURL' et de terminer le thread, donc tuer la connexion à l'URL? – conorgriffin

+0

Très probablement, oui. –

+0

A droite, 'fetchXMLFromURL:' retourne immédiatement 'parseInBackground'. Mais voir la réponse de Rob Keniger. –

2

Vous libérez le NSURLConnection dès que vous le créez, ce qui signifie qu'il est immédiatement désalloué. Vous ne devez pas libérer le NSURLConnection jusqu'à ce que vous receviez un message de délégué qui vous indique que l'opération est terminée ou a échoué pour une raison quelconque.

+0

Ok, mais la version n'est pas un problème si j'appelle 'fetchXMLFromURL' sans thread. – conorgriffin

+0

@Rob Keniger voir mise à jour sur la question s'il vous plaît, merci – conorgriffin