Brad Larson は、スクロール ビューがスクロールしているときにフリーズする問題の解決策を提供しました。CADisplayLink
私の OpenGL ES 描画メソッドは a によって呼び出され、CADisplayLinkBrad の手法を試しましたが、うまくいきません。中心的な問題は、私の OpenGL ES ビューが によってホストされておりUIScrollView、UがIScrollViewスクロールするとが起動しなくなるCADisplayLinkことです。
Brad が説明した手法は、CADisplayLinkスクロール中でも (NSRunLoopCommonModesデフォルトの runloop モードの代わりに追加することで) を起動し続けることになっています。忙しすぎる。
問題は、セマフォのトリックによってレンダリング コールバックが何があっても描画されないことです。
最初に、シリアル 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];
render コールバックは Brad の手法を実行します。
- (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ため、render コールバックは決してレンダリングしません。スクロールしていないときでも。
ここで何か重要なことを見逃していたと思います。誰かがそれを指摘できますか?
編集:dispatch_syncの代わりに呼び出す場合にのみ機能するようですdispatch_asyncが、ブラッドによると、dispatch_asyncここでより良いパフォーマンスが得られます。