CADisplayLink に大きな問題があることがわかりました。
テスト用に回転する三角形を描画する OpenGL ES 1.1 を使用した最も基本的な EAGLLayer があります。これには、画面のリフレッシュ レートで実行ループ メソッドを呼び出す必要があるため、次のように実行ループを開始します。
- (void)startRunloop {
if (!animating) {
CADisplayLink *dl = [[UIScreen mainScreen] displayLinkWithTarget:self selector:@selector(drawFrame)];
[dl setFrameInterval:1.0];
[dl addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
self.displayLink = dl;
animating = YES;
}
}
- (void)stopRunloop {
if (animating) {
[self.displayLink invalidate];
self.displayLink = nil;
animating = NO;
}
}
テスト アプリが起動したら、-startRunloop を呼び出します。画面をタップすると、-stopRunloop が呼び出されます。もう一度タップすると、-startRunloop が呼び出されます。などなど。卓球。
-drawFrame メソッドが 20 秒間に呼び出される頻度を測定し、NSLog します。
FIRST の開始 / 停止サイクルは常に 100% で実行されます。最大フレームレートを取得します。
すべての SUBSEQUENT 開始/停止サイクルは、パフォーマンスの約 80% しか示していません。フレームレートが大幅に低下します。ただし: 常にほぼ同じで、+/- 2 フレームです。さらに50回の始動/停止サイクルの後でも、さらに劣化する傾向はありません。
結論として、無効にするか一時停止するまでは、上記のように CADisplayLink を作成しても問題ありません。その後、新しい CADisplayLink はうまく機能しなくなります。新しく、以前とまったく同じ方法で作成された場合でも。-setPaused: メソッドを YES / NO で呼び出して一時停止 / 再開する場合も同様です。
Allocations と VM Tracker Instruments でメモリ管理の問題がないことを確認しました。また、CADisplayLink の -invalidate メソッドが実際に呼び出されることも確認しました。
デバイスの iOS 4.0 (iPhone 4)。
何故ですか?何か不足していますか?