2015-04-29 62 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%的时间)宁愿让你的代码异步运行 –