布拉德·拉尔森发表了解决方案的CADisplayLink
时滚动视图滚动冻结问题。
我的OpenGL ES绘制方法是通过一个名为CADisplayLink
,我试图布拉德的技术,但不能使它工作。 核心问题是,我的OpenGL ES视图是由托管UIScrollView
,并当U IScrollView
滚动时, CADisplayLink
停止射击。
布拉德描述的技术应该让CADisplayLink
继续开火,即使在滚动(将其添加到NSRunLoopCommonModes
而不是默认的runloop模式),并且使用一个奇特的信号伎俩呈现回调应该确保它不会渲染时UIKit的太占用。
问题是,虽然信号量伎俩阻止执行回调从图纸,不管是什么。
首先,我创建的串行GCD队列和信号灯initWithFrame
我的OpenGL ES查看像这样(在主线程)方法:
frameRenderingQueue = dispatch_queue_create("com.mycompany.crw", DISPATCH_QUEUE_SERIAL);
frameRenderingSemaphore = dispatch_semaphore_create(1);
显示链接被创建并添加到NSRunLoopCommonModes
:
CADisplayLink *dl = [[UIScreen mainScreen] displayLinkWithTarget:self selector:@selector(renderFrame)];
[dl addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
渲染回调执行布拉德的技术:
- (void)renderFrame {
if (dispatch_semaphore_wait(frameRenderingSemaphore, DISPATCH_TIME_NOW) != 0) {
NSLog(@"return"); // Gets called ALWAYS!
return;
}
dispatch_async(drawingQueue, ^{
@autoreleasepool {
// OpenGL ES drawing code
dispatch_semaphore_signal(frameRenderingSemaphore);
}
});
}
该dispatch_semaphore_wait
函数总是返回YES
,从而呈现回调从未呈现。 即使我不滚动。
我想,我错过了这里的东西很重要。 有人能指出来?
编辑:看来,只有当我打电话给工作dispatch_sync
而不是dispatch_async
,但据布拉德dispatch_async
会在这里提供更好的性能。