Objective c 如何以非阻塞方式检查iOS上的网络可达性?

Objective c 如何以非阻塞方式检查iOS上的网络可达性?,objective-c,ios,reachability,Objective C,Ios,Reachability,在我的iOS项目中,我希望在某些网络操作之前向用户显示一条连接到internet的消息,因此我使用Apple的可达性类编写了以下检查: Reachability *reach = [Reachability reachabilityWithHostName:@"google.com"]; if([reach currentReachabilityStatus] == NotReachable) { // ...prompt user to establish an internet co

在我的iOS项目中,我希望在某些网络操作之前向用户显示一条连接到internet的消息,因此我使用Apple的可达性类编写了以下检查:

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上的上行数据包丢失设置为100%时),
[Reachability Reachability with hostname:@“google.com”]
将在确定连接不可用之前阻塞主线程30秒。但是,以下代码不会阻止:

if([[Reachability reachabilityForInternetConnection] currentReachabilityStatus] == NotReachable) {
    // ...prompt user to establish an internet connection
} else {
    // ...send an asynchronous request with a timeout
}

查看可达性的实现可以看出,这两种方法都使用
SystemConfiguration.framework
,但第一种方法使用
SCNetworkReachabilityCreateWithName
,而第二种方法使用
SCNetworkReachabilityCreateWithAddress
。为什么第一个方法阻塞,而第二个方法不阻塞?第二种方法是检查连通性的好方法吗?或者有更好的方法吗?

第一种方法测试它是否可以访问
google.com
,而第二种方法只是检查是否有任何可能的互联网连接(它认为有,即使有数据包丢失)

基本上只是把它放在一个线程或后台队列中。可靠地知道连接是否良好的唯一方法是测试它,任何测试都将是阻塞或异步的。您根本无法立即使用它。

请检查此功能:

- (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;

}
}

这将很好地工作。

请您解释一下,您如何能够确定地声明第二种方法仅检查是否可以连接?文件中是否有说明?如果您能给我一个源代码,我会将此标记为正确答案。任何I/O活动都必须是阻塞的或异步的,才能告诉您它是否可以执行某些操作。在您的示例代码中,您展示了它是同步的,并且可以立即返回。逻辑上的结论是不涉及I/O。这可能不是
SCNetworkReachabilityCreateWithName
SCNetworkReachabilityCreateWithAddress
之间的区别,而是
InternetConnection的可达性检查套接字地址为零,从而跳过了对远程主机进行检查的时间密集型任务?我只是想要一个合乎逻辑的解释,说实话,我是一个比较务实的人。第一个检查它是否实际工作,第二个根据一些本地缓存的信息进行猜测。这不是你需要知道的全部吗?我想对我来说已经足够了。我的意思是,无论如何,你可以在请求本身附加一个失败块。但是如果你想检查一个数据包是否可以交付,这也不起作用