2

我有一个 Cocoa 应用程序,它从内部启动一个新的 NSThread(线程 A) applicationDidFinishLaunching

线程 A 成功创建了一个 RFCOMM 连接,然后生成另一个 NSThread(线程 B),将已建立的 IOBluetoothRFCOMMChannel 传递给线程 B。线程 B 创建一个 IOBluetoothRFCOMMChannelDelegate 并使用它调用 IOBluetoothRFCOMMChannel 上的 setDelegate,然后运行其当前的 NSRunLoop。然后线程 A 等待线程 B 发出同步对象的信号。

目的是,当数据到达时,线程 B 的 NSRunLoop 将执行复制接收到的数据并通知线程 A 读取它的委托。

但是,委托永远不会被调用,因为线程 B 的 NSRunLoop 没有输入源。我想象 setDelegate 会在上面创建一个输入源。我可以调用委托的唯一方法是让线程 A 等待它自己的 NSRunLoop 而不是等待同步对象。在这种情况下,委托会被执行。

但这种安排对我不起作用。最终,我的代码将只是一个库,它公开了一个标准的 C API,并且只适合作为一组程序流动的函数。线程 A 将是其他人的线程(可能是主线程,也可能不是),并且将以程序方式调用我的库。

1)我认为注册委托回调(线程B)的线程/运行循环是获取输入源并在其运行循环中执行回调的线程/运行循环。但是线程 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
4

1 回答 1

3

IOBluetooth 和线程很乱。您必须通过反复试验来解决这些问题。如果回调似乎发生在打开连接的线程上,那么您必须在需要回调的线程上打开连接。此外,这种行为经常在操作系统版本之间发生变化......

于 2012-06-06T22:50:23.817 回答