Что не так с этим многопоточным кодом Objective-C для моего приложения для iPhone? - PullRequest
3 голосов
/ 17 февраля 2010

Этот кусок кода:

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

вызывает этот код:

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

Однако, когда я перехожу через него в отладке, как только он возвращается к '}' в fetchXMLFromURL, он возвращается в строку:

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

и соединение с URL-адресом, извлекающим XML, фактически никогда не запускается. Кто-нибудь есть идеи, почему?


Эта исправленная версия, кажется, работает правильно, кто-нибудь может обнаружить какие-либо потенциальные проблемы?

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

Пересмотрен снова, надеюсь, исправим сейчас

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

Ответы [ 2 ]

4 голосов
/ 17 февраля 2010

Да.Используемый вами метод NSURLConnection сам по себе асинхронный - он вызывает несколько различных методов делегата (как указано в протоколе NSURLConnectionDelegate) при получении данных.В этом случае вам лучше всего использовать метод +sendSynchronousRequest:returningResponse:error: или NSData +dataWithContentsOfURL:options:error:, так как оба из них будут блокировать выполнение в фоновом потоке (что нормально) до тех пор, пока они не завершат получение вашегоданные.Также убедитесь, что вы установили видимость индикатора сетевой активности перед началом синхронного запроса.

2 голосов
/ 17 февраля 2010

Вы отпускаете NSURLConnection, как только вы его создаете, что означает, что он немедленно освобожден. Вы не должны выпускать NSURLConnection до тех пор, пока не получите сообщение делегата о том, что операция завершена или по какой-то причине произошла ошибка.

...