Brad Larson は、スクロール ビューがスクロールしているときにフリーズする問題の解決策を提供しました。CADisplayLink
私の OpenGL ES 描画メソッドは a によって呼び出され、CADisplayLink
Brad の手法を試しましたが、うまくいきません。中心的な問題は、私の 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
ここでより良いパフォーマンスが得られます。