为什么Reachability Manager无法检测到互联网?

我正在学习AFNetworking。 当我运行下面的代码,我得到没有互联网。 但在另一个检查说,它连接到互联网和设备通过WiFi连接到互联网。 这个输出:

2016-02-19 15:16:40.315 AFNetworkingSample[377:47927] There is no internet connection 2016-02-19 15:16:40.331 AFNetworkingSample[377:47927] Reachability: Reachable via WiFi 

任何想法为什么连接方法的返回值是错误的?

 - (void)viewDidLoad { [super viewDidLoad]; [[AFNetworkReachabilityManager sharedManager] startMonitoring]; if (self.connected) { NSLog(@"We have internet connection"); } else { NSLog(@"There is no internet connection"); } [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { NSLog(@"Reachability: %@", AFStringFromNetworkReachabilityStatus(status)); }]; } -(BOOL)connected { return [AFNetworkReachabilityManager sharedManager].reachable; } 

更新当我改变它跟随它工作正常,并正确地检测互联网。 任何人都可以解释此行为?

 [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { NSLog(@"Reachability: %@", AFStringFromNetworkReachabilityStatus(status)); if (self.connected) { NSLog(@"We have internet connection"); } else { NSLog(@"There is no internet connection"); } }]; 

UPDATE2

当我等待两秒钟,它检测到互联网正常:

 double delayInSeconds = 2.0; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ if (self.connected) { NSLog(@"We have internet connection"); } else { NSLog(@"There is no internet connection"); } }); 

UPDATE3:

这是如何练习,以避免竞争条件?

 - (void)viewDidLoad { [super viewDidLoad]; [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { NSLog(@"Reachability: %@", AFStringFromNetworkReachabilityStatus(status)); if([AFNetworkReachabilityManager sharedManager].reachable) { NSLog(@"Internet connection started again"); } else { UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Alert" message:@"Error Retrieving Data" preferredStyle:UIAlertControllerStyleActionSheet]; UIAlertAction *firstAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { NSLog(@"You pressed button OK"); }]; [alert addAction:firstAction]; [self presentViewController:alert animated:YES completion:nil]; } }]; double delayInSeconds = 2.0; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ [[AFNetworkReachabilityManager sharedManager] startMonitoring]; }); } 

  [[AFNetworkReachabilityManager sharedManager] startMonitoring]; 

以上是有效的asynchronous调用。 你已经告诉AFNetwork你对可达性感兴趣。 因此,它将会停下来,做任何需要做的事来确定和监控后台的可达性。

由于它不是一次性asynchronous调用,因此在该方法上具有完成块并不适合正常完成处理程序的模式。 它可能是一个“状态处理程序”,每当状态发生变化时就被调用,但API也被devise用于被动轮询(其中一些其他的代码模式,如定时器,无意中这样做)正如你所指出的那样,没有足够长的时间给你错误的答案,如预期的那样)。

通过调用setReachabilityStatusChangeBlock:当可达性状态改变时,你正在注册一些代码来执行。 使用它来触发你的“嘿!可达性改变!” 代码,一切都很好。


剩下的唯一问题是是否存在竞争条件。 您应该在调用startMonitoring之前设置该块。 而且,为了安全起见,在调用startMonitoring之后,您可能需要检查networking是否立即连接,因为在技术上,如果networking已连接,则可能没有状态变化触发您的状态改变处理程序块。


你不想阻塞线程2秒,试图避免竞争条件。 做这样的事情:

 ... set up change handler block ... ... start monitoring ... ... check current internet state & alert user if necessary ... 

将您的警报移出更改处理程序块,并将其更改为上面提及的更改处理程序块和“检查当前互联网状态和警报用户”(如果需要)的方法。

使用像这样的可达性…..

 - (void)viewDidLoad { if (self.isConnected) { NSLog(@"We have internet connection"); } else { NSLog(@"There is no internet connection"); } } -(BOOL)isConnected { Reachability *aReachability = [Reachability reachabilityWithHostName:KWebserviceURL]; NetworkStatus netStatus = [aReachability currentReachabilityStatus]; if(netStatus==0) { // NoAccess return NO; } else if(netStatus==1) { // ReachableViaWiFi return YES; } else if(netStatus==2) { // ReachableViaWWAN return YES; } else { // Reachable return YES; } } 

如果你想使全球classror检查互联网连接,然后让NSObject看到我的另一个答案…. 检查这里

希望它能帮助你…