我正在尝试学习AFNetworking。当我运行以下代码时,我无法上网。但是在另一项检查中,它说它已连接到Internet,并且设备通过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];

上面是有效的异步调用。您已经告诉AFNetwork您对可达性感兴趣。因此,它将在后台确定并监视可达性所需的一切工作。

由于它不是单次异步调用,因此在该方法上具有完成块实际上不适合常规完成处理程序的模式。可能是状态变化发生时都会调用的“状态处理程序”,但该API还设计用于被动轮询(您的某些其他代码模式(例如计时器)会无意中这样做-并且,正如您指出的那样,等待时间不够长会给您错误的答案,正如预期的那样)。

通过调用setReachabilityStatusChangeBlock:,您正在注册一些可访问性状态更改时要执行的代码。使用它触发您的“嘿!可达性已更改!”代码,一切都很好。

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

您不想在2秒钟内阻塞线程以尝试避免出现竞争状况。做这样的事情:
... set up change handler block ...
... start monitoring ...
... check current internet state & alert user if necessary ...

将您的警报移出更改处理程序块,并移至上述更改处理程序块和“检查当前的互联网状态和警报用户(如果需要)”两者均可调用的方法。

关于ios - 为什么可达性管理器无法检测到Internet?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35497269/

10-13 04:01