3

私の iOS プロジェクトでは、特定のネットワーク操作の前にインターネットに接続するようにユーザーにメッセージを表示したいので、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
}

ただし、これには 1 つの非常に大きな問題がありました。デバイスが非常に損失の多いネットワーク上にある場合 (たとえば、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し、2 番目のメソッドは を使用していますSCNetworkReachabilityCreateWithAddress。最初のメソッドはブロックするのに、2 番目のメソッドはブロックしないのはなぜですか? 2 番目の方法は、接続を確認する良い方法ですか? それとももっと良い方法がありますか?

4

2 に答える 2

4

この機能をチェックしてください:

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

}
}

これはうまくいきます..

于 2012-11-26T10:32:58.117 に答える
2

1 つ目は に到達できるかどうかをテストgoogle.comし、2 つ目はインターネット接続が可能かどうかを単純にチェックします (パケット損失があっても接続可能と見なされます)。

基本的には、スレッドまたはバックグラウンド キューに入れるだけです。接続が良好かどうかを確実に知る唯一の方法は、接続をテストすることであり、どのテストもブロックまたは非同期になります。すぐに利用できるようにすることはできません。

于 2012-07-03T16:09:04.747 に答える