菜鸟教程小白 发表于 2022-12-13 14:35:45

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


                                            <p><p>我正在尝试学习 AFNetworking。当我运行以下代码时,我得到没有互联网。但在另一项检查中,它说它已连接到互联网,并且设备通过 wifi 连接到互联网。这是输出:</p>

<pre><code>2016-02-19 15:16:40.315 AFNetworkingSample There is no internet connection
2016-02-19 15:16:40.331 AFNetworkingSample Reachability: Reachable via WiFi
</code></pre>

<p>知道为什么连接方法的返回值为假吗?</p>

<pre><code>- (void)viewDidLoad {

    ;
    [ startMonitoring];



    if (self.connected)
    {
      NSLog(@&#34;We have internet connection&#34;);
    }
    else
    {
      NSLog(@&#34;There is no internet connection&#34;);
    }


    [ setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
      NSLog(@&#34;Reachability: %@&#34;, AFStringFromNetworkReachabilityStatus(status));
    }];

}


-(BOOL)connected {

   return .reachable;

}
</code></pre>

<p><strong>更新</strong>
当我将其更改为跟随时,它可以正常工作并正确检测互联网。任何人都可以解释这种行为吗?</p>

<pre><code>[ setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
    NSLog(@&#34;Reachability: %@&#34;, AFStringFromNetworkReachabilityStatus(status));

    if (self.connected)
    {
      NSLog(@&#34;We have internet connection&#34;);
    }
    else
    {
      NSLog(@&#34;There is no internet connection&#34;);
    }

}];
</code></pre>

<p><strong>更新2</strong></p>

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

<pre><code>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(@&#34;We have internet connection&#34;);
    }
    else
    {
      NSLog(@&#34;There is no internet connection&#34;);
    }

});
</code></pre>

<p>更新3:</p>

<p>这是避免竞态条件的练习方法吗?</p>

<pre><code>- (void)viewDidLoad {
    ;
    [ setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {

      NSLog(@&#34;Reachability: %@&#34;, AFStringFromNetworkReachabilityStatus(status));
      if(.reachable)
      {
            NSLog(@&#34;Internet connection started again&#34;);
      }
      else
      {
            UIAlertController *alert = [UIAlertController alertControllerWithTitle:@&#34;Alert&#34;
                                                                           message:@&#34;Error Retrieving Data&#34;
                                                                  preferredStyle:UIAlertControllerStyleActionSheet];
            UIAlertAction *firstAction = [UIAlertAction actionWithTitle:@&#34;OK&#34;
                                                                  style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
                                                                      NSLog(@&#34;You pressed button OK&#34;);
                                                                  }];
            ;
            ;
      }
    }];
    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){
      [ startMonitoring];
    });
}
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><pre><code>      [ startMonitoring];
</code></pre>

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

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

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

<hr/>

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

<hr/>

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

<pre><code>... set up change handler block ...
... start monitoring ...
... check current internet state &amp; alert user if necessary ...
</code></pre>

<p>将您的警报从更改处理程序 block 中移出,并移到更改处理程序 block 和上面提到的“检查当前互联网状态并在必要时提醒用户”都可以调用的方法中。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 为什么可达性管理器无法检测到互联网?,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/35497269/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/35497269/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 为什么可达性管理器无法检测到互联网?