2012-01-20 2 views
3

Я отредактировал это сообщение, чтобы было проще читать, я думаю.iOS dispatch_async и функции делегата NSURLConnection, не называемые

Мне нужно вызвать NSUrlConnection после того, как я закончил интенсивную обработку строк в блоке dispatch_async.

URL-адрес, который я вызываю, получил на нем аутентификацию .htaccess, поэтому я не могу использовать синхронное соединение.

Но методы делегата NSURLConnection не вызываются. Я знаю, что URL-адрес загружается примерно через 5 секунд в браузере, и я проверил код с простым URL-адресом без аутентификации, и это не имеет никакого значения.

Что останавливает методы делегата?

Эта функция делает некоторые манипуляции строки вещи, и требуется некоторое время, чтобы закончить:

- (void)performSearch { 

    // set some defaults and work out if it is a valid search, setting bSearchOk 

    if (bSearchOk) { 

     // update some interface elements 
     self.msgBox.text = @"Translating...";    
     self.plateInput.enabled = NO; 
     self.searchProgress.hidden = NO; 

     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

      // create a new search 
      Search *oPlateSearch = [[Search alloc] initWithTerm:thisTerm]; 

      // ... 
      // perform search... this calls a variety of slow and intensive functions 
      // ... 

      self.aFinalPlates = [oPlateSearch.aValidated copy]; 
      self.aCurrentPlates = [oPlateSearch.aFinals copy];   

      dispatch_async(dispatch_get_main_queue(), ^{     
       [oPlateSearch release];    

       // make ajax call to check if plates can be bought 
       [self getPrices];     
      }); 
     }); 

    } else { 
     // hide results 
     self.searchResults.hidden = YES; 
    } 

} 

И это одна называется к концу блока выше

/* call to get plate availability and prices */ 
-(void) getPrices { 
    // set return message 
    self.msgBox.text = @"Getting prices and availability"; 

    // ... 
    // then I build my strRequest var, which is a valid working URL 
    // ... 

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:strRequest]]; 

    NSURLConnection *loginConnection = [[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease]; 

    NSLog('This will get logged'); 

    if(loginConnection) { 
     NSLog('This will also get logged'); 
     self.jsonSearchResponse = [[[NSMutableData data] retain] autorelease]; 
     NSLog('And this will get logged, so it's not throwing errors'); 
    } else { 
     NSLog(@"Failed to get search results"); 
    } 
} 

Update: Я так как это было принято в ответ на другой аналогичный вопрос, но он не сработал:

NSURLConnection *loginConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO]; 
[loginConnection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; 
[loginConnection start]; 

Основано на этом вопросе: Why NSURLConnection delegate methods don't get called, when using the global dispatch queue?

ответ

4

Кто-то из iphonedevsdk.com форум ответил на это для меня:

http://www.iphonedevsdk.com/forum/iphone-sdk-development/97415-dispatch_async-nsurlconnection.html

Ответ был использовать:

[self performSelectorOnMainThread:@selector(getPrices) withObject:Nil waitUntilDone:NO]; 
+0

Почему это исправляет проблему? –

+1

Я не совсем уверен, но, судя по имени функции «performSelectorOnMainThread», когда поток, который я запускаю, заканчивается, он вызывает метод в основном потоке программы. –

+1

Может быть, вы действительно не решили проблему, потому что ваш вызов getPrices в основном потоке теперь, а не в глобальной очереди отправки, как вы изначально хотели? –

0

Я думаю, что вы автореализовываете соединение и не храните никаких ссылок на него, так что он выходит из памяти. Удалите вызов автоответчика и проверьте, не исчезла ли проблема. Если это так, просто найдите способ освободить соединение, когда вы закончите с ним, чтобы он не просочился.

+0

Я пробовал, не работает I 'Боюсь. Я переместил выпуск в методы connectionDidFinishLoading и connectionDidFail, но он работает точно так же –

3

Я начал SO пост, который показывает, как использовать NSURLConnection с dispatch_async и сконфигурировать NSRunLoop

NSURLConnection blocking wrapper implemented with semaphores

Кусок кода, который был бы заинтересован в это:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
    NSURLRequest* request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10]; 
    [NSURLConnection connectionWithRequest:request delegate:self]; 

    while(!self.finished) { 
     [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; 
    } 
}); 

и в connectionDidFinishLoading, установите finished на YES:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection { 
    self.finish = YES; 
} 
Смежные вопросы