1

BT デバイスからデータを読み取るアプリを Mac に移植しています。Mac 固有のコードでは、-(void) rfcommChannelData:(...) のような BT コールバックのデリゲート メソッドを持つクラスがあります。

そのコールバックで、受信したデータでバッファーを埋めます。アプリから呼び出される関数があります。

-(int) m_timedRead:(unsigned char*)buffer length:(unsigned long)numBytes time:(unsigned int)timeout
{

double steps=0.01;
double time = (double)timeout/1000;
bool ready = false;
int read,total=0;
unsigned long restBytes = numBytes;
while(!ready){
    unsigned char *ptr = buffer+total;
    read = [self m_readRFCOMM:(unsigned char*)ptr length:(unsigned long)restBytes];
    total+=read;
    if(total>=numBytes){
        ready=true; continue;
    }
    restBytes = numBytes-total;
    CFRunLoopRunInMode(kCFRunLoopDefaultMode, .4, false);       
    time -= steps;
    if(time<=0){
        ready=true; continue;
    }
}

私の問題は、この RunLoop がアプリ全体を非常に遅くすることです。デフォルト モードを使用せず、runlooptimer を使用して on runloop を作成すると、コールバック メソッド rfcommChannelData が呼び出されません。次のコードを使用して、1 つの実行ループを作成します。

//  CFStringRef myCustomMode = CFSTR("MyCustomMode");
//  CFRunLoopTimerRef myTimer;
//  myTimer = CFRunLoopTimerCreate(NULL,CFAbsoluteTimeGetCurrent()+1.0,1.0,0,0,foo,NULL);   
//  CFRunLoopAddTimer(CFRunLoopGetCurrent(), myTimer, myCustomMode);
//  CFRunLoopTimerInvalidate(myTimer);
//  CFRelease(myTimer);

デフォルトの RunLoop がアプリ全体を遅くする理由、または自分の実行ループを作成して rfcommchannel からのコールバックがトリガーされるようにする方法はありますか?

どうもありがとう、

アントン・アルバヘス・エイザギレ

4

1 に答える 1

1

GUI アプリのメイン スレッドで作業している場合は、独自のメソッドに対して内部的に実行ループを実行しないでください。実行ループ ソースをインストールし (または、フレームワークの非同期 API が代わりにソースをインストールできるようにします)、メイン イベント ループに戻ります。つまり、実行フローがコードから戻り、呼び出し元に戻るようにします。メイン イベント ループはメイン スレッドの実行ループを実行し、ソースの準備が整うと、それらのコールバックが起動され、おそらくメソッドが呼び出されます。

于 2012-04-27T23:33:36.203 に答える