NSURLConnection
を使う際、非同期通信を基本にすべきですが、反応速度が重要でない場合は同期でやってしまいたいこともあります。
ただし、sendSynchronousRequest
を使うと、NSURLRequest
で指定したtimeoutIntervalは無
視されるようで、不正なURLを指定した場合などに強制的に30秒以上待たされます。
「同期通信で、タイムアウトを5秒くらいにしたラッパーを作りたい」と思い、非同期通信を行い、通信が完了するまでwhileループで待つようなことを試してみました。
response = nil; //responseはvolatile指定したインスタンス変数
[NSURLConnection connectionWithRequest:request delegate:self];
while (response == nil) {
[NSThread sleepForTimeInterval:1]; //1行待ってみる
NSLog(@"待っています・・・");
}
このようにして、データを受け取るconnection
メソッドでは、インスタンス変数response
に結果を格納するようにします。
・・・しかし、この方法では永久に「待っています・・・」と表示されて、いつまでたっても受信されません。
理由
理由は、connectionWithRequest
自体は別スレッドで実行されるものの、その結果となるconnection
はメインスレッドで実行されるためです。
つまり、whileループのあるメソッドが終了するまで、プールに溜まるだけでconnection
メソッドが実行されないということみたいです。
また、connectionWithRequest
そのものを別スレッドにする方法では、NSThread
はjoin
に相当するものが無いため、即座に親スレッドが終了し、connection
が呼ばれる前に子スレッドも終了されてしまいます。
残念ながら、pthread
でjoin
するような力業を使わない限り、「同期通信で、タイムアウトを5秒くらいにしたラッパーを作りたい」という目標は実現が難しそうです。
どなたか良い解決案をお持ちでしたら、是非教えて下さい。
そもそもtimeoutIntervalが無視されたり、joinが無いなどというのはライブラリの欠陥な気がするのですが・・・
- 解決編をご覧ください。