コールバック関数が呼び出されない場合 : Objective-C プログラミング

PROGRAM


コールバック関数が呼び出されない場合

Xcode 4 で静的ライブラリを作成している際に、その中で実装した Core Foundation 式のコールバック関数が呼び出されないことがありました。

具体的には CFSocket を用いてパケットの受信待ちを行うプログラムを Cocoa の Static Library 内に実装していたのですけど、パケットを受信した際に呼び出されるコールバック関数を CFSocketCreate 関数を使って登録したものの、パケットが到着してもそれが呼び出されないという状況でした。

 

原因について調べてみると、CFSocket を CFRunLoopAddSource でランループに関連付けるスレッドが CFRunLoopGetCurrent 関数で取得したものを指定していたのが原因でした。

もう少し詳しく調べてみると、CFRunLoopGetCurrent 関数が呼び出される箇所を performSelectorInBackground メソッドを使用して、バックグラウンドで動作させていたことが影響していたようでした。

どうやら performSelectorInBackground で呼び出されたバックグラウンドのスレッドでは、カレントのランループが停止しているようなため、そこに CFRunLoopAddSource で入力ソースを追加しても、それが実行されない感じです。

 

これはつまり、NSThread を新規に "detachNewThreadSelector:toTarget:withObject:" で立ち上げて、そのまま CFRunLoopRun 関数を実行していない、通常の状況と同じ感じなのかもしれないですね。

呼び出された機能の中で CFRunLoopRun 関数を実行すれば、コールバック関数が呼び出されるようにもなるようですけど、それよりは、performSelectorInBackground で CFRunLoopGetCurrent を使用しないか、もしどうしても performSelectorInBackground 内でランループを利用する必要があるのであれば、CFRunLoopGetMain を使用してメインスレッドを使用するなどの配慮が必要になるようでした。

[ もどる ]