在我的 iOS 项目中,我想在某些网络操作之前向用户显示一条连接到 Internet 的消息,所以我使用 Apple 的 Reachability 类编写了以下检查:
Reachability *reach = [Reachability reachabilityWithHostName:@"google.com"];
if([reach currentReachabilityStatus] == NotReachable) {
// ...prompt user to establish an internet connection
} else {
// ...send an asynchronous request with a timeout
}
然而,这有一个非常大的问题——当设备在一个非常有损的网络上时(例如,当 OS X Lion 的Network Link Conditioner上的上行链路数据包丢失设置为 100% 时),[Reachability reachabilityWithHostName:@"google.com"]
会阻塞主线程 30 秒之前确定连接不可用。但是,以下代码不会阻塞:
if([[Reachability reachabilityForInternetConnection] currentReachabilityStatus] == NotReachable) {
// ...prompt user to establish an internet connection
} else {
// ...send an asynchronous request with a timeout
}
查看 Reachability 的实现表明这两种方法都使用SystemConfiguration.framework
,但第一种方法使用SCNetworkReachabilityCreateWithName
,而第二种方法使用SCNetworkReachabilityCreateWithAddress
。为什么第一种方法会阻塞,而第二种方法不会呢?第二种方法是检查连通性的好方法吗?或者,还有更好的方法?