我有一个Cocoa应用程序,它从applicationDidFinishLaunching中启动一个新的NSThread (线程A)。
线程A成功地创建了一个RFCOMM连接,然后生成另一个NSThread (线程B),将已建立的IOBluetoothRFCOMMChannel传递给线程B。线程B创建一个IOBluetoothRFCOMMChannelDelegate,并使用它在IOBluetoothRFCOMMChannel上调用setDelegate,然后运行它当前的NSRunLoop。然后,线程A等待线程B发信号通知同步对象。
这样做的目的是,当数据到达时,线程B的NSRunLoop将执行复制接收到的数据的委托,并向线程A发出信号来读取它。
但是,委托永远不会被调用,因为线程B的NSRunLoop没有输入源。我想象setDelegate会在上面创建一个输入源。调用委托的唯一方法是让线程A在自己的NSRunLoop上等待,而不是在同步对象上等待。在这种情况下,委托将被执行。
但这种安排对我不起作用。最终,我的代码将只是一个库,它公开了一个C API,这是一个标准,并且只适合作为一组流程化的函数。线程A将是别人的线程(可能是main,也可能不是),它会以一种过程化的方式调用我的库。
1)我认为注册委托回调的线程/ runloop (线程B)将获得输入源并在其runloop中执行回调。但是线程A的NSRunLoop获取的是输入源,为什么呢?这些事物之间的预期关系是什么?
2)如何让线程B获取输入源,并成为执行委托的线程?
感谢大家的帮助。
我的线程B如下:
@implementation CBaiHardwareBluetoothEventThread
- (void) runEventThread: (IOBluetoothObjectID)deviceID
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSRunLoop* myRunLoop = [NSRunLoop currentRunLoop];
CallbackDelegate* cd = [[CallbackDelegate alloc] init];
IOBluetoothRFCOMMChannel* myOBJCChannel = [IOBluetoothRFCOMMChannel withObjectID:deviceID];
[myOBJCChannel setDelegate:cd];
do{
[myRunLoop runUntilDate:[NSDate distantFuture]];
cout << __FUNCTION__ << " this should not be returning but it is ???" << endl;
usleep(1000000);//avoid the unintentional hard loop that happens
}while(1); //forever for now
[pool release];
}
@end发布于 2012-06-07 06:50:24
IOBluetooth和线程是乱七八糟的。你必须通过反复试验来解决这个问题。如果回调似乎发生在打开连接的线程上,那么您必须在需要回调的线程上打开连接。此外,此行为通常在不同的操作系统版本之间发生变化...
https://stackoverflow.com/questions/10923112
复制相似问题