FacebookがAsyncDisplayKitをオープンソースとして公開した。元々は,旧型のデバイス上でもアプリのスムーズな動作と応答性の維持を容易に保証する,同社のPaperアプリのために開発されたフレームワークだったものだ。
AsyncDisplayKitの最も大きなメリットは,Facebookによると,複雑なビュー階層を生成および描画するためのイメージおよびテキストビューを,完全にメインスレッド以外で動作させることが可能な点だ。広く知られているように,ユーザ操作が適切な扱われることを保証するには,処理をメインスレッド外に移すことが非常に重要である。さらに,処理をバックグラウンドスレッドに任せれば,マルチコアアーキテクチャのメリットを活用することも可能になる。
iOSにはGrand Central DispatchやNSOperationsなど,これを行う方法がいくつも用意されている。しかしUIの主要な処理部分であるUIKitが安全に使用できるのは,相変わらずメインスレッドに限定されたままだ。
ユーザエクスペリエンスのスムーズさを保証するには,各UIの更新を数ミリ秒のみに実行するという時間的制限を満たす必要がある。UIImageView
やUITextView
のようにメインスレッドのみで動作するUIKitビューでは,これを満足するのは非常に難しい。グラフィックスやテキストに関連する複雑な処理のため,それ自体のサイズ変更や表示に数十ないし数百ミリ秒を要するためだ。
この問題を解決するために,通常はCoreGraphicやCoreTextなど,より低いレベルのフレームワークを使ってイメージやテキスト表示を処理する。この場合は低レベルの,ARC(Automatic Reference Counting / 自動参照カウント)に対応しないC言語APIの処理が必要になる。
AsyncDisplayKitはUIKit, CoreAnimation,CoreTextを基盤として,ASImageNodeとASTextNodeという名称の,それぞれUIImageViewとUITextViewのドロップイン・リプレースメントを提供する。さらに,メインスレッドをブロックすることなくセルノードを非同期にプリロード可能なASTableView
クラスも提供されている。
使用方法
AsyncDisplayKit階層は前述のように,バックグラウンドスレッドで初期化やレイアウトすることができる。
dispatch_async(_backgroundQueue, ^{ ASTextNode *node = [[ASTextNode alloc] init]; node.attributedString = [[NSAttributedString alloc] initWithString:@"hello!" attributes:nil]; [node measure:CGSizeMake(screenWidth, FLT_MAX)]; node.frame = (CGRect){ CGPointZero, node.calculatedSize }; // self.viewはnodeではないのでメインスレッドでのみ利用可能 dispatch_sync(dispatch_get_main_queue(), ^{ [self.view addSubview:node.view]; }); });
この処理では,ASTextNode
オブジェクトが生成されるまで,メインスレッドがブロックされることはない。最後の部分では,メインスレッド上で通常のUIView
にASTextNode
オブジェクトを追加しているが,ここからAsyncDisplayKitオブジェクトとUIKitのオブジェクトに互換性があることを確認できる。
AsyncDisplayKitのもうひとつの興味深い特徴は,layerBacked
プロパティを設定することで,ビュー階層をレイヤ階層に変換可能な点だ。これにより,Core Animation APIに明示的なビューベースのコードを実装しなくても,よりパフォーマンスのよい方法に移行することが可能になる。
AsyncDisplayKitは,以前にInfoQが報告したPop以降,Facebookがオープンソースにした2つめのフレームワークである。