NSRunLoop和GCD队列

时间:2011-03-02 00:21:30

标签: iphone ios grand-central-dispatch nsrunloop avcapturesession

我正在创建一个在iOS上使用的c ++库(是的,不幸的是它必须是C ++),它使用AVCaptureSession来捕获视频帧,这些视频帧是通过captureOutput回调传递的。 C ++库是我的可交付产品。我有一个可可触摸应用程序来测试/演示它。所以,它看起来像这样:

(测试应用)< -----> (c ++ lib(AVFoundation callbacks))

测试应用程序具有UI控件,几乎负责所有图形。 c ++库通过OpenGL将帧渲染到UIView。

你跟我在一起吗?好


好的,首先,用户按下一个UIButton,它会调用我的库。此调用需要10秒或更长时间才能完成。因此,如果我将调用直接放在按钮单击后面,UI将被阻止,直到库函数返回:

-(IBAction)hBut:(id)sender{
    [myLib foo]; // takes 10+ seconds to return
}

这不好。我尝试的下一件事是产生一个线程来调用lib:

-(void)callIntoLib{
    [myLib foo];
}

-(IBAction)hBut:(id)sender{
    [NSThread detach..:myLib selector:foo object:nil];
}

这不再阻止UI,但现在视频帧回调函数永远不会触发(AVCaptureSession的captureOutput)。似乎主NSRunLoop已被阻止。

接下来我尝试了同样的事情,但是使用Grand Central Dispatch:

-(IBAction)hBut:(id)sender{
     _myQueue = dispatch_queue_create("com.domain.me", NULL); // member variable
     dispatch_async(_myQueue,
     ^{
          [myLib foo];
     });
}

这有相同的行为。也就是说,视频帧的回调不会触发。拉梅

为什么主要的NSRunLoop在第二和第三种情况下被阻止?有没有办法将队列与它相关联?

这有意义吗?

2 个答案:

答案 0 :(得分:2)

主线程自行运行其runLoop,因此在第一种情况下,来自相机的事件被传送到您的库。自定义线程不运行runLoop,你应该自己动手。

-(void)callIntoLib {
    [myLib foo];
    self.callIntoLibExecuted = YES;
}


-(void)threadBody {
    @autoreleasepool {
        self.callIntoLibExecuted = NO;

        [self performSelector:@selector(callIntoLib) 
                 onThread:[NSThread currentThread] 
                 withObject:nil
                 waitUntilDone:NO];

        while (!self.callIntoLibExecuted)
        {
           @autoreleasepool {
               [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
                         beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
           }
        }
    }
}

-(IBAction)hBut:(id)sender {
    [NSThread detachNewThreadSelector:@selector(threadBody) 
              toTarget:self withObject:nil];
}

答案 1 :(得分:0)

此示例代码仅在GCD Serial Queue上使用AVCaptureVideoDataOutput -setSampleBufferDelegate:queue :.似乎AVCaptureSession必须与RunLoop一起使用。您需要在线程上执行自己的RunLoop,或尝试修改您的C ++ lib作为此示例代码。

相关问题