2012-01-20 76 views
3

我已經編輯了這篇文章,使它更易於閱讀,我想。iOS dispatch_async和NSURLConnection委託函數沒有被調用

我需要在dispatch_async塊中完成一些密集的字符串操作後調用NSUrlConnection。

我調用的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"); 
    } 
} 

更新:我我也試過這個,因爲它是對另一個類似問題的答案,但它沒有奏效:

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

有人論壇回答了這個對我來說:

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,而不是像你最初所期望的那樣在全局調度隊列中調用getPrices? –

0

我認爲你正在autoreleasing連接,並沒有保留任何引用,以便它內存不足。刪除autorelease調用,看看問題是否消失。如果是這樣,只要找到一種方法來釋放連接,這樣它就不會泄漏。從iphonedevsdk.com

+0

我已經試過了,沒有工作,我'我害怕。我將該版本移入了connectionDidFinishLoading和connectionDidFail方法,但它以完全相同的方式運行 –

3

我已經開始了一個SO後它展示瞭如何使用NSURLConnectiondispatch_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; 
} 
相關問題