首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么Reachability不能检测到internet?

为什么Reachability不能检测到internet?
EN

Stack Overflow用户
提问于 2016-02-19 04:22:48
回答 2查看 1.3K关注 0票数 2

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

代码语言:javascript
复制
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

知道为什么连接方法的返回值是假的吗?

代码语言:javascript
复制
- (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;

}

更新时,我把它改为跟随它工作很好,并正确地检测互联网。有人能解释这种行为吗?

代码语言:javascript
复制
[[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

当我等待两秒钟时,它就能正确地检测到互联网:

代码语言:javascript
复制
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:

这是如何练习,以避免比赛条件?

代码语言:javascript
复制
- (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];
    });
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-02-19 04:47:46

代码语言:javascript
复制
      [[AFNetworkReachabilityManager sharedManager] startMonitoring];

实际上,上面的是一个异步调用。您已经告诉AFNetwork您对可达性感兴趣。因此,它将启动并做它需要做的任何事情来确定和监视背景中的可达性。

由于它不是一个一次性异步调用,因此在该方法上有一个完成块并不完全符合正常完成处理程序的模式。它可能是一个“状态处理程序”,每当发生状态更改时都会调用它,但是API也被设计成用于被动轮询(您的一些其他代码模式,比如计时器模式,不经意间就会这样做--正如您所注意到的,等待时间不够长会给出错误的答案,正如您所期望的那样)。

通过调用setReachabilityStatusChangeBlock:,当可达状态发生变化时,您将注册要执行的一些代码。用它来触发你的“嘿!可达性改变了!”密码,一切都好。

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

您不希望阻塞线程2秒,以尝试避免争用条件。做这样的事:

代码语言:javascript
复制
... set up change handler block ...
... start monitoring ...
... check current internet state & alert user if necessary ...

将您的警报移出更改处理程序块,进入一个方法,上面提到的更改处理程序块和“检查当前internet状态&警报用户”都可以调用该方法。

票数 1
EN

Stack Overflow用户

发布于 2016-02-19 04:29:59

像这样使用可实现性.

代码语言:javascript
复制
- (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;
    }
}

如果您想使全局类错误检查internet连接,那么让NSObject在我的其他ans中看到.Check here

希望它能帮你..。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35497269

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档