2012-09-27 40 views
1

當滾動視圖滾動時,Brad Larson爲CADisplayLink凍結問題提供了solution即使我沒有滾動,爲什麼dispatch_semaphore_wait()始終返回YES?

我的OpenGL ES繪製方法是由CADisplayLink調用的,我嘗試了Brad的技術,但無法使其工作。核心問題是我的OpenGL ES視圖由UIScrollView託管,當U IScrollView滾動時,CADisplayLink停止觸發。

描述布拉德應該讓CADisplayLink繼續開火,即使在滾動(將其添加到NSRunLoopCommonModes而不是默認的runloop模式),並且使用一個奇特的信號欺騙呈現回調的技術應該確保它不當UIKit被佔用太多時渲染。

問題是雖然信號量技巧阻止渲染回調繪製,不管怎麼樣。

首先,我創建在我的這樣的OpenGL ES視圖的initWithFrame方法串行GCD隊列和信號量(在主線程):

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,因此render回調從不呈現。即使我沒有滾動。

我想我錯過了重要的東西在這裏。有人能指出嗎?

編輯:這似乎只有當我打電話dispatch_sync而不是dispatch_async,但根據布拉德dispatch_async會在這裏給更好的表現工作。

回答

0

我不得不把代碼的結構改成這樣:

- (void)renderFrame { 
    dispatch_async(drawingQueue, ^{ 
     if (dispatch_semaphore_wait(frameRenderingSemaphore, DISPATCH_TIME_NOW) != 0) { 
      return; 
     } 

     @autoreleasepool { 
      // Drawing code... 
     } 

     dispatch_semaphore_signal(frameRenderingSemaphore); 
    }); 
} 

後,我重組它這樣,dispatch_semaphore_wait呼叫停止回是所有的時間。我不確定這是否僅僅是禁用Brad的信號量等待技巧。但它的工作。

相關問題