0

URL のロードが時々失敗する状況を見ていますが、それは非常に「ひどく」失敗します。ホストに到達できない (つまり、VPN が接続されていない) 場合+[NSURLConnection(NSURLConnectionReallyInternal) _resourceLoadLoop:]、次のバックトレースでハングすることがよくあります。

(gdb) bt
#0  in mach_msg_trap ()
#1  in mach_msg ()
#2  in __CFRunLoopServiceMachPort ()
#3  in __CFRunLoopRun ()
#4  in CFRunLoopRunSpecific ()
#5  in +[NSURLConnection(NSURLConnectionReallyInternal) _resourceLoadLoop:] ()
#6  in -[NSThread main] ()
#7  in __NSThread__main__ ()
#8  in _pthread_start ()
#9  in thread_start ()

を実装- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)errorしましたが、呼び出されません。

次のように NSURLRequest を作成しています。

NSURLRequest *theRequest = 
    [NSURLRequest requestWithURL:[NSURL URLWithString:url]
                     cachePolicy:NSURLRequestReloadIgnoringCacheData
                 timeoutInterval:5.0];

そのため、リクエストは無期限にハングアップするのではなく、5 秒後にタイムアウトするはずだと想定していました。これは起こっていません。

これは、Mac OS X のコンソール アプリケーション (iOS ライブラリのテスト フレームワーク) 内で発生することに注意してください。実行ループ構成で何か「奇妙な」ことが起こっているのではないかと思っています。(トレースから、実行中の実行ループ内から新しい実行ループをスピンアップしようとしているように見えます?!)

何か案は?

編集:これは Cocoa アプリケーションではないため、実行ループを手動で実行する必要があります。これはおそらく問題の一部のようです。

4

2 に答える 2

1

あなたが提供したタイムアウトが作動するように見えることに同意します。バグがある可能性があります。

接続を試みる前にネットワークの到達可能性を確認することで、問題をある程度改善できる場合があります。SCNetworkReachability APIを参照してください。

実行ループ (フレームワークがバックグラウンドで実行されているスレッドではなく、制御するスレッドで実行されているもの) にタイマーをインストールし、起動時に接続をキャンセルすることで、独自のタイムアウトを課すこともできます。

于 2012-05-10T02:03:50.870 に答える
0

私は問題を解決しました。この問題は、実行ループに十分な時間を与えなかったために発生しました。私はこれに似たコードを持っていました:

[[NSRunLoop currentRunLoop] runUntilDate:
    [NSDate dateWithTimeIntervalSinceNow:5];

これにより、実行ループが5秒間実行されただけで、URLConnectionからコールバックが失敗したことを通知しないのに十分な時間でした。私はそれをもっとこのようなものに変更しました、そしてそれはうまくいきました:

[[NSRunLoop currentRunLoop] runUntilDate:
    [NSDate dateWithTimeIntervalSinceNow:10];

バックトレースで見られるこれの副作用は、URLConnectionオブジェクトがコールバックを作成しようとしたときに、実行ループが停止したことを検出する方法がなくmach_msg_trap、応答を待っている可能性が高いことです。受け取る。その振る舞いを完全に説明することはできませんが、それが一般的な理論です。;-)

于 2012-05-10T06:07:35.313 に答える