简体   繁体   English

可达性示例应用程序为何在这里停滞?

[英]Why does Reachability sample app stall here?

Apple's sample app named Reachability shows how to detect connections. 苹果公司名为Reachability的示例应用程序展示了如何检测连接。 If you have only wifi but not internet, the app stalls for over a minute on the second line below: 如果您只有wifi上网,但没有互联网,则该应用会在下面的第二行中暂停一分钟以上:

SCNetworkReachabilityFlags reachabilityFlags;
BOOL gotFlags = SCNetworkReachabilityGetFlags(reachabilityRef, &reachabilityFlags);

SCNetworkReachabilityGetFlags comes from SystemConfiguration.framework. SCNetworkReachabilityGetFlags来自SystemConfiguration.framework。 Any suggestions on how to get around this? 关于如何解决这个问题的任何建议?

To answer your question directly, no, there doesn't seem to be any way to "get around" SCNetworkReachabilityGetFlags() taking a long time to return under the specific circumstances you described (eg, checking remote host reachability via WiFi connection to a router with no Internet). 要直接回答您的问题,不,似乎没有任何方法可以解决您所描述的特定情况下需要花费很长时间才能返回的SCNetworkReachabilityGetFlags()(例如,通过与路由器的WiFi连接检查远程主机的可达性)没有互联网)。 A couple of options: 有两个选择:

OPTION 1. Make the call in a separate thread so that the rest of your app can keep running. 选项1.在一个单独的线程中进行调用,以便您的其他应用程序可以继续运行。 Modify ReachabilityAppDelegate.m as follows for an example: 修改ReachabilityAppDelegate.m作为示例:

// Modified version of existing "updateStatus" method
- (void)updateStatus
{
    // Query the SystemConfiguration framework for the state of the device's network connections.
    //self.remoteHostStatus           = [[Reachability sharedReachability] remoteHostStatus];
    self.remoteHostStatus = -1;
    self.internetConnectionStatus   = [[Reachability sharedReachability] internetConnectionStatus];
    self.localWiFiConnectionStatus  = [[Reachability sharedReachability] localWiFiConnectionStatus];
    [tableView reloadData];

    // Check remote host status in a separate thread so that the UI won't hang
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSTimer *timer = [NSTimer timerWithTimeInterval:0 target:self selector:@selector(updateRemoteHostStatus) userInfo:nil repeats:NO];
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
    [pool release];
}
// New method
- (void) updateRemoteHostStatus
{
    self.remoteHostStatus = [[Reachability sharedReachability] remoteHostStatus];
    [tableView reloadData];
}

OPTION 2. Use a different API/function that uses a timeout value when trying to connect to the remote host. 选项2.尝试连接到远程主机时,请使用使用超时值的其他API /函数。 That way your app would only hang for X seconds before it gives up. 这样一来,您的应用在放弃之前仅会挂起X秒钟。

Some other things to note: 其他注意事项:

  • The specific call to SCNetworkReachabilityGetFlags() that you're asking about (ie, line ~399 in Reachability.m) is trying to see if www.apple.com is "reachable" to deduce if "the external internet" is "reachable" in general. 您正在询问的对SCNetworkReachabilityGetFlags()的特定调用(即Reachability.m中的〜399行)试图查看www.apple.com是否“可访问”,以推断“外部互联网”是否“可访问”一般来说。
  • In Apple's System Config framework "reachable" might not mean what you think it does. 在Apple的System Config框架中,“可达”可能并不意味着您认为的那样。 According to the official docs, "reachable" seems to mean that, in theory, your computer could connect to host X if it wanted to, but it might need to actually establish a connection first (eg, dial a modem first). 根据官方文档,“可达”似乎意味着,从理论上讲,您的计算机可以连接到主机X,但实际上可能需要先建立连接(例如,先拨打调制解调器)。 In other words, SCNetworkReachabilityGetFlags() doesn't actually establish a connection. 换句话说,SCNetworkReachabilityGetFlags()实际上并未建立连接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM