afmotionで応答を同期的に待つ

| コメント(0) | トラックバック(0)

あまり褒めらた方法ではないのですが、処理を簡単にするためAFNetworkingでの通信を同期で行いたいことはありますよね。

AFNetworkingのNSOperationQueuewaitUntilAllOperationsAreFinishedを呼んでやればできるのかとおもいきや、どうも意味が違うらしい。

そこで簡単に思いつくGCDのSemaphoreを使ってコールバックが終わるまで待つようにしてみたところ...

client.getのところで実行がデッドロックしているようでコールバックブロックが呼ばれません。

APIのログを確認するとサーバにアクセスは来ています。

これ、結構ハマってしまい諦めて別の方法で実装しようかなと思ってたのですが「Are AFNetworking success/failure blocks invoked on the main thread?」を発見してcompletionQueueの存在を知ります。

たぶんここcompletionQueueが設定されていない場合、dispatch_get_main_queue()が使われるのでデッドロックするのだと思われます。

dispatch_get_global_queueとかdispatch_queue_createとかしたものをセットすれば良さそうです。

先ほどのRubyMotionのafmotionを介して実行したサンプルですとAFMotion::Client.buildのDSLブロックに

   :
  response_serializer :json
  completion_queue Dispatch::Queue.concurrent
end

とかできれば良かったのですが、ClientDSLクラスには定義されてないようです。(プルリクチャンスかw) ただ返されるclientAFHTTPRequestOperationManagerそのもののようなので使う前に設定してみます。

client.completionQueue = Dispatch::Queue.concurrent

EXC_BAD_ACCESSります。RubyMotionのDispatch::Queueオブジェクトは元のGCDオブジェクトそのものではないので当然か。Dispatch::Queue.concurrent.methodsでメソッドを見てみるとdispatch_objectなんてものがありますので、おそらくコレですね。

期待通りに動くようになりました( ˘ω˘)



トラックバック(0)

トラックバックURL: http://www.iwazer.com/mt/mt-tb.cgi/1814

コメントする

このブログ記事について

このページは、iwazerが2014年8月26日 14:50に書いたブログ記事です。

ひとつ前のブログ記事は「iOS Simulatorに簡単にたくさんの画像を入れる方法」です。

次のブログ記事は「Xcode6.2のままiOS8.3の実機に転送する」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。