Почему NSURLConnection блокирует мой пользовательский интерфейс? - PullRequest
0 голосов
/ 10 августа 2010

Я читал несколько веток и вопросов по этой проблеме, но не нашел решения.

У меня есть несколько асинхронных вызовов, выполненных с

[NSURLConnection connectionWithRequest:anURLRequest delegate:self];

Проблема в том, что я хочу, чтобы интерфейс работал, но он заблокирован, пока соединение не будет установлено.

Это решается запуском другого потока? Где именно проблема?

EDIT

Хорошо, после получения данных я анализирую их с помощью NSXMLParser, которые делают это синхронно и блокируют основной поток. Это правильно? Тогда, может быть, мне нужно разобрать в другой теме. У кого-нибудь есть руководство?

Ответы [ 5 ]

1 голос
/ 07 февраля 2011

Не знаю, может ли это кому-нибудь помочь, но у меня такая же проблема (асинхронный URL-запрос блокирует пользовательский интерфейс), но это было из-за:

NSLog(@"dataReceived: %@", data);

в методе connectionDidReceiveData.

1 голос
/ 10 августа 2010

Пользовательский интерфейс не должен блокироваться при использовании connectionWithRequest. Попробуйте создать метку в своем пользовательском интерфейсе и обновите в своем соединении текущий объем данных, например:

- (void)downloadContentFromUrl:(NSURL *)url {   
    NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0];
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    if (connection) {
        receivedData = [[NSMutableData data] retain];
        self.downloadProgressLabel.text = @"Downloading...";
    } else {
        // oh noes!
    }
}

- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    [receivedData setLength:0]; 
}

- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {   
    [receivedData appendData:data]; 
    int kb = [receivedData length] / 1024;
    self.downloadProgressLabel.text = [NSString stringWithFormat:@"Downloaded\n%d kB", kb];
}

connectionWithRequest действительно работает в своем собственном потоке - вам не нужно беспокоиться об этом. На самом деле это должно быть запущено из основного потока. Проверьте NSUrlConnection документ для получения дополнительной информации.

1 голос
/ 10 августа 2010
+ (id)connectionWithRequest:(NSURLRequest *)request delegate:(id)delegate];

Этот метод должен создать асинхронный запрос (это означает, что он работает в фоновом режиме и не блокирует пользовательский интерфейс).Вы должны проверить, есть ли в вашем файле другой класс / метод, который блокирует пользовательский интерфейс (например, NSData '+ (NSData *) dataWithContentsOfURL: (NSURL *) URL').

1 голос
/ 10 августа 2010

Из документов:

Сообщения делегату будут отправляться в потоке, который вызывает этот метод. Для правильной работы соединения цикл выполнения вызывающего потока должен работать в режиме цикла выполнения по умолчанию.

Вы уверены, что этот код вызывается в цикле выполнения в режиме по умолчанию, а не из потока, созданного вами с помощью другого типа режима цикла выполнения?

0 голосов
/ 24 февраля 2012

В моем случае я пытался обновить свойство UIProgressView.progress.Я вычислил новое значение следующим образом:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
    [self.progress setProgress:self.downloadedData.length / self.fileSize ];
    [self.downloadedData appendData:data];
}

, которое не работает, я заменил этот фрагмент кода на

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
    self.downloadedSize += data.length;
    [self.progress setProgress:self.downloadedSize / self.fileSize ];
    [self.downloadedData appendData:data];
}

И теперь представление прогресса отображается без проблем.*

...