为啥可达性示例应用程序在这里停滞不前?
Posted
技术标签:
【中文标题】为啥可达性示例应用程序在这里停滞不前?【英文标题】:Why does Reachability sample app stall here?为什么可达性示例应用程序在这里停滞不前? 【发布时间】:2009-04-06 22:14:29 【问题描述】:Apple 名为 Reachability 的示例应用程序展示了如何检测连接。如果您只有 wifi 而没有互联网,应用程序会在下面的第二行停止超过一分钟:
SCNetworkReachabilityFlags reachabilityFlags;
BOOL gotFlags = SCNetworkReachabilityGetFlags(reachabilityRef, &reachabilityFlags);
SCNetworkReachabilityGetFlags 来自 SystemConfiguration.framework。有关如何解决此问题的任何建议?
【问题讨论】:
【参考方案1】:要直接回答您的问题,不,似乎没有任何方法可以“绕过” SCNetworkReachabilityGetFlags() 在您描述的特定情况下需要很长时间才能返回(例如,通过 WiFi 连接检查远程主机可访问性到没有互联网的路由器)。几个选项:
选项 1. 在单独的线程中进行调用,以便您的应用程序的其余部分可以继续运行。修改 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];
选项 2. 在尝试连接到远程主机时使用使用超时值的不同 API/函数。这样一来,您的应用只会挂起 X 秒后放弃。
其他一些注意事项:
您询问的对 SCNetworkReachabilityGetFlags() 的特定调用(即 Reachability.m 中的第 ~399 行)试图查看 www.apple.com 是否“可访问”以推断“外部互联网”是否为“可达”一般。 在 Apple 的系统配置框架中,“可访问”可能并不意味着您认为它的作用。根据官方文档,“可达”似乎意味着,理论上,您的计算机可以根据需要连接到主机 X,但它可能需要先实际建立连接(例如,先拨打调制解调器)。换句话说,SCNetworkReachabilityGetFlags() 实际上并没有建立连接。【讨论】:
谢谢。如何创建超时,以便在达到超时间隔时返回回调?如果在超时间隔之前调用 UIWebViewDelegate::webViewDidFinishLoad,我可以取消超时。 看看 NSTimer 的 scheduleTimerWithTimeInterval: 方法。您可以在当前线程中创建一个计时器,例如,在 5 秒后执行某个方法。此方法可以检查 SCNetworkReachabilityGetFlags() 是否已完成,如果尚未完成,则运行您的超时逻辑。以上是关于为啥可达性示例应用程序在这里停滞不前?的主要内容,如果未能解决你的问题,请参考以下文章