2

の完了ルーチンで

[NSURLConnection sendAsynchronousRequest:request
                                   queue:queue
                       completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)

呼んでいます

dispatch_async(dispatch_get_main_queue(), ^
{
  NSLog(@"CALLING SUCCESS");
});

2 つのテスト アプリケーションがあります。1 つは正しく動作し、もう 1 つは正しく動作しません。何が起こるかというと、ログ ステートメントは実行されません。キューはで作成されました

queue = [[NSOperationQueue alloc] init];

私を夢中にさせて、それは単に実行をまったく拒否します。どちらの場合も、アプリケーションの起動中にこれを呼び出しました。電話を5秒遅らせてみました。私が何をしても、あるアプリではブロックを実行しませんが、他のアプリでは実行します。どのような状況でdispatch_async(dispatch_get_main_queue()...が失敗する可能性があるかについての手がかりがあれば、違いを見分けることができるかもしれません。

実際のコードでは、メイン スレッドで実行するブロックを呼び出していることに注意してください。テスト ケースを NSLog の呼び出しだけに減らしました。

更新: 違いは、このコードは iOS 5.1 シミュレーターでは機能しませんが、6.0 または 6.1 では機能することです。なんで?

更新 2: OK、デフォルトの NSURLConnection を使用すると動作しますが、使用すると

self.connection = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:NO];
[self.connection setDelegateQueue:queue];
[self.connection start];

iOS 5.1 では動作しません。これは 5.1 の setDelegateQueue のバグではないかと考え始めています。

4

1 に答える 1

0

OK、本当の問題はこれです。NSURLConnection のクラス メソッドを使用する場合

+ (void)sendAsynchronousRequest:(NSURLRequest *)request
                      queue:(NSOperationQueue *)queue
          completionHandler:(void (^)(NSURLResponse *, NSData *, NSError *))handler

iOS 5 または 6 では、すべて正常に動作します。

代わりに (私が行ったように) 独自の接続ハンドラーを実装する場合、つまり、NSURLConnectionDelegate と NSURLConnectionDataDelegate を実装し、呼び出して、(私の場合はキャッシュを回避するために) クラス メソッドに相当する独自のものをロールします。

self.connection = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:NO];
[self.connection setDelegateQueue:queue];
[self.connection start];

この場合、dispatch_async は iOS 5.X では機能しませんが、iOS 6.X では機能します。Appleがバグを修正したと思います。

于 2013-03-12T16:13:52.693 に答える