2011-12-07 8 views
12

私はCADisplayLinkに大きな問題を認識しました。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が呼び出されます。その他卓球。

私は20秒で-drawFrameメソッドが呼び出される頻度を測定しています。

  • FIRSTの開始/停止サイクルは常に100%で実行されます。私は最大のフレームレートを取得します。

  • すべての後続開始/停止サイクルは、パフォーマンスの約80%しか示していません。私はかなり小さいフレームレートを取得します。しかし、常にほぼ正確に+/- 2フレーム。さらに50回の起動/停止サイクルを経てもさらに劣化する傾向はありません。結論として

:それは無効または一時停止されるまで私は上記のように行うCADisplayLinkの作成は、罰金です。その後、新しいCADisplayLinkはそれ以上はうまく機能しません。たとえそれが以前とまったく同じように新しく作られたとしても。 YES/NOを指定して-setPaused:メソッドを呼び出すことで、一時停止/再開する場合も同じです。

割り当てやVMトラッカーインストゥルメントでは、メモリ管理の問題がないことを確認しました。また、CADisplayLinkの-invalidateメソッドが実際に呼び出されたことを確認しました。

端末(iPhone 4)のiOS 4.0。

なぜですか?何か不足していますか?

+0

これを試してみてください。あなたはAppleにバグレポートを提出する必要があると思います。 –

+0

私は同じ問題があります。 DisplayLinkはいつも動く必要はありませんが、私は選択肢がないようです。今はisPausedを使用する代わりにハンドラセレクタでフラグを使用しています。 –

答えて

1

開始コールごとに新しい表示リンクインスタンスを作成します。あなたは同じインスタンスを再利用しようとしましたか?

また、表示リンクを一時停止することもできます。私は

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

を使用しています

5

は、それはあなた

5

のために働く場合、私はあなたが何が本当にしたいことは、あなたの表示リンクを一時停止し、一時停止を解除するだけだと思います参照してください。

- (void)createRunloop { 
    CADisplayLink *dl = [[UIScreen mainScreen] displayLinkWithTarget:self selector:@selector(drawFrame)]; 
    [dl setFrameInterval:1.0]; 
    [dl addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
    self.displayLink = dl; 
    // start in running state, your choice. 
    dl.paused = NO; 
} 
- (void)startRunloop { 
    self.displayLink.paused = NO; 
} 
- (void)stopRunloop { 
    self.displayLink.paused = YES; 
} 
- (void)destroyRunloop { 
     [self.displayLink invalidate]; 
     self.displayLink = nil; 
} 
0

それはバグのように聞こえる、スウィフトに

displayLink?.remove(from: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode) 
関連する問題