如何以非阻塞的方式检查iOS上的networking可达性?

在我的iOS项目中,我想显示一条消息给用户在某些networking操作之前​​连接到互联网,所以我使用苹果的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 } 

但是,这有一个非常大的问题 – 当设备在非常有损耗的networking上时(例如,在OS X Lion的networking链路调节器上将上行链路丢包设置为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 。 为什么第一个方法阻止,而第二个方法阻止? 第二种方法是检查连通性的好方法吗? 或者,还有更好的方法?

第一个testing是否可以到达google.com ,而第二个只是检查是否有任何互联网连接可能(它认为有,即使有数据包丢失)。

基本上只是把它放在一个线程或后台队列中。 可靠地知道你是否有良好的连接的唯一方法是testing它,任何testing将被阻止或asynchronous。 你根本无法立即得到它,永远。

检查这个function:

 - (BOOL)isNetworkAvailable { CFNetDiagnosticRef diag; diag = CFNetDiagnosticCreateWithURL (NULL, (__bridge CFURLRef)[NSURL URLWithString:@"www.apple.com"]); CFNetDiagnosticStatus status; status = CFNetDiagnosticCopyNetworkStatusPassively (diag, NULL); CFRelease (diag); if ( status == kCFNetDiagnosticConnectionUp ) { //NSLog (@"Connection is up"); return YES; } else { NSLog (@"Connection is down"); return NO; } } 

这将工作得很好..