2012-04-27 57 views
1

我正在將一個應用程序從BT設備讀取數據移植到Mac。在特定於mac的代碼中,我有一個帶有BT回調委託方法的類,如 - (void)rfcommChannelData:(...)CFRunLoop無阻塞等待緩衝區填充

在該回調函數中,我用接收的數據填充緩衝區。我有一個從應用程序調用的函數:

-(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創建我的runloop,則回調方法rfcommChannelData永遠不會被調用。創建我的一個runloop用下面的代碼:

// 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回調被觸發?

非常感謝,

安東Albajes-Eizagirre

回答

1

如果您在GUI應用程序的主線程上工作,不要在內部運行的運行循環,以自己的方法。安裝運行循環源代碼(或者允許框架的異步API代表您安裝源代碼)並返回主事件循環。也就是說,讓執行流程返回代碼並返回給調用者。主事件循環運行主線程的運行循環,並且當源代碼準備就緒時,它們的回調將會觸發,這可能會調用您的方法。