15

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)。

何故ですか?何か不足していますか?

4

6 に答える 6

5

私は使っている

[displayLink removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

それがあなたのために働くかどうか見てください

于 2015-07-16T18:58:50.710 に答える
2

すべての開始呼び出しで、新しい表示リンク インスタンスを作成します。同じインスタンスを再利用しようとしましたか?

また、いつでも表示リンクを一時停止できます。

于 2011-12-31T23:42:12.653 に答える
0

Swiftでこれを試してください、

displayLink?.remove(from: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)
于 2016-11-23T11:34:09.573 に答える