• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

ios - 为什么可达性管理器无法检测到互联网?

[复制链接]
菜鸟教程小白 发表于 2022-12-13 14:35:45 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

我正在尝试学习 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");
    }

}];

更新2

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

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");
    }

});

更新3:

这是避免竞态条件的练习方法吗?

- (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];
    });
}



Best Answer-推荐答案


      [[AFNetworkReachabilityManager sharedManager] startMonitoring];

以上实际上是一个异步调用。您已告诉 AFNetwork 您对可达性感兴趣。因此,它将启动并执行它需要做的任何事情来确定和监控后台的可达性。

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

通过调用 setReachabilityStatusChangeBlock:,您正在注册一段代码,以便在可达性状态更改时执行。用它来触发你的“嘿!可达性改变了!”代码,一切正常。


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


您不想将线程阻塞 2 秒以尝试避免竞争条件。做这样的事情:

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

将您的警报从更改处理程序 block 中移出,并移到更改处理程序 block 和上面提到的“检查当前互联网状态并在必要时提醒用户”都可以调用的方法中。

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

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap