2015-04-29 87 views
0

我是iOS開發新手。我已經搜索並嘗試了幾種方法,但程序不想等待異步調用完成。Objective C - 如何等待異步調用完成

調試時,函數CheckForHost首先返回-1作爲retVal。這會導致調用函數的方法繼續。稍後,程序返回到CheckForHost函數,將正確的值設置爲retVal。我也試過用NSCondition,但沒有運氣要麼...

有人可以告訴我我做錯了什麼或應該做不同嗎?非常感謝您的幫助!

下面的代碼:

-(int)CheckForHost 
 
{ 
 
    InternetActive = -1; 
 
    HostActive = -1; 
 
    dispatch_queue_t myQueue = dispatch_queue_create("my queue", NULL); 
 
    __block int retVal = -1; 
 
    dispatch_async(myQueue, ^{ 
 
     [self HostInit]; 
 
     dispatch_async(dispatch_get_main_queue(), ^{ 
 
      [internetReachable stopNotifier]; 
 
      [hostReachable stopNotifier]; 
 
      [[NSNotificationCenter defaultCenter] removeObserver:self]; 
 
      if (InternetActive == 0) { 
 
       retVal = 0; 
 
      } else if (HostActive == 0) { 
 
       retVal = 1; 
 
      } else 
 
       retVal = 2; 
 
     }); 
 
    }); 
 
    return retVal; 
 
} 
 

 
-(void)HostInit 
 
{ 
 
    // check for internet connection 
 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkNetworkStatus:) name:kReachabilityChangedNotification object:nil]; 
 
    internetReachable = [Reachability reachabilityForInternetConnection]; 
 
    [internetReachable startNotifier]; 
 
    // check if a pathway to a random host exists 
 
    hostReachable = [Reachability reachabilityWithHostName:@"www.apple.com"]; 
 
    [hostReachable startNotifier]; 
 
    // now patiently wait for the notification 
 
} 
 

 
-(void)checkNetworkStatus:(NSNotification *)notice 
 
{ 
 
    // called after network status changes 
 
    NetworkStatus internetStatus = [internetReachable currentReachabilityStatus]; 
 
    switch (internetStatus) 
 
    { 
 
     case NotReachable: 
 
     { 
 
      NSLog(@"The internet is down."); 
 
      InternetActive = 0; 
 
      break; 
 
     } 
 
     case ReachableViaWiFi: 
 
     { 
 
      NSLog(@"The internet is working via WIFI."); 
 
      InternetActive = 1; 
 
      break; 
 
     } 
 
     case ReachableViaWWAN: 
 
     { 
 
      NSLog(@"The internet is working via WWAN."); 
 
      InternetActive = 1; 
 
      break; 
 
     } 
 
    } 
 
    NetworkStatus hostStatus = [hostReachable currentReachabilityStatus]; 
 
    switch (hostStatus) 
 
    { 
 
     case NotReachable: 
 
     { 
 
      NSLog(@"A gateway to the host server is down."); 
 
      HostActive = 0; 
 
      break; 
 
     } 
 
     case ReachableViaWiFi: 
 
     { 
 
      NSLog(@"A gateway to the host server is working via WIFI."); 
 
      HostActive = 1; 
 
      break; 
 
     } 
 
     case ReachableViaWWAN: 
 
     { 
 
      NSLog(@"A gateway to the host server is working via WWAN."); 
 
      HostActive = 1; 
 
      break; 
 
     } 
 
    } 
 
}

+1

你打這個電話的線程是什麼?你永遠不要在UI線程中等待。使用某種完成處理程序。 –

回答

0

我會用塊,他們很容易和可靠

下面是一個例子功能塊:

- (void)checkForHostWithBlock:(void (^)(int myReturnedInt))completion{ 

//Our function does stuff here, i'll copy paste some of your code 

InternetActive = -1; 
    HostActive = -1; 
    dispatch_queue_t myQueue = dispatch_queue_create("my queue", NULL); 
    __block int retVal = -1; 
    dispatch_async(myQueue, ^{ 
     [self HostInit]; 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      [internetReachable stopNotifier]; 
      [hostReachable stopNotifier]; 
      [[NSNotificationCenter defaultCenter] removeObserver:self]; 
      if (InternetActive == 0) { 
       retVal = 0; 
      } else if (HostActive == 0) { 
       retVal = 1; 
      } else 
       retVal = 2; 
      if (completion){ 
       completion(retVal); 
      } 
     }); 
    }); 
} 

你走了。

您可以像調用其他任何方法一樣調用該方法,並且可以使用自動完成來確保將所有內容正確寫入。

[self checkForHostWithBlock:^(int myReturnInt){ 
    //Executed code when the block is called in checkForHost: 
    NSLog(@"Here is my int : %i !!", myReturnInt); 
}]; 

請注意,block參數可以爲零,但您需要確保在您的方法中檢查它。

+0

非常感謝這個例子。有效!!! –

+0

請確保您瞭解這是如何工作的,不要複製粘貼它!但無論如何,歡迎您:) –

0

好吧,如果你想等待執行完畢,你不應該異步執行它。異步的含義是不要等待。

因此,如果您想等待,請同步執行該程序段或使用semaphore。 (我沒有說這是被同步。我只是說,怎樣做才能執行好主意。)

+0

感謝您的意見。我已將CheckForHost從dispatch_async更改爲dispatch_sync兩個實例。在那種情況下,我從來沒有得到任何回報。將該函數中的第二個實例更改爲dispatch_async,可以獲得與我的問題中所述相同的結果。由於我是iOS新手,你能告訴我在上面的代碼中要糾正什麼嗎?謝謝。 –

+0

那麼,如果你想讓它同步,就不要使用塊,而是一行一行地寫代碼。但是,正如我在我的A中所說的那樣,更好的方法是異步保持它併爲該塊提供完成處理程序。但是這導致了GCD的基本解釋。文檔對此更好。 –

+0

同步執行代碼時要小心,它會凍結在代碼運行時在側面運行的任何東西。我想我們可以放心地說,你通常(99%的時間)寧願讓你的代碼異步運行 –