CADisplayLinkというの知らなかったのでメモ

今度転職するのに備えて現在iOSリハビリ中です 汗。

少し前にリリースしたiOSアプリに簡単なgifアニメーションを再生しようと思ってライブラリ探していてとりあえずFlipboardのFLAnimatedImageというのに辿り着いた。

Flipboard/FLAnimatedImage · GitHub

でソースみてたのですが、CADisplayLinkというのが今まで見たことなかったものがあったので少し調べてみたのでそのメモ。

CADisplayLinkとは

CADisplayLinkクラスのAppleのリファレンスを日本語に訳してくれてるサイトが以下。

CADisplayLinkクラス | Second Flush

まあこれ見ればもう使い方とかは十分なんですがねw
簡単にいえば、画面が更新されたる度に処理をしたいときに使うもの、って認識でいいと思う。

NSTimerでええんでないの??

で、それってNSTimerでやれることじゃない?という話になると思う。
そこで検索してみると以下の記事が参考になった。

Technical Q&A QA1385: Driving OpenGL Rendering Loops

これはCVDisplayLink(Core Video)についての話だけど気にしなくてOKなはず。

要はパフォーマンスの話で、NSTimerだと設定した時間毎に処理を行おうとするため(タイマーが発火したことにより行われている1つ前の処理がまだ終わっていないにも関わらず、次のタイマーが発火して次の処理を行おうとする)処理がどんどん重たくなっていくが、CVDisplayLink(及びCADisplayLink)はそういったところを換算してくれる、ということだと思う。

使い方

まずQuartzCoreをimportする。

#import <QuartzCore/QuartzCore.h>

でCADisplayLinkのインスタンスをdisplayLinkWithTargetメソッドで生成する。この際に、描画更新毎に呼ばれるセレクターを設定する。
また、生成されたCADisplayLinkのインスタンスをNSRunLoopのメインループに追加してあげる。

CADisplayLink *_displayLink;
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayDidRefresh:)];
[_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

あとはセレクターを書いてあげればOK

- (void)displayDidRefresh:(CADisplayLink *)displayLink
{
    NSLog(@"called displayDidRefresh");
}

最後に忘れてならないのは、このままだとずっとアプリケーション起動中に処理が走ってしまうので、invalidateしてあげること。

- (void)dealloc
{
    [_displayLink invalidate];
}