2013年4月23日火曜日

tumblr製 モダンな非同期2段キャッシュライブラリ

非同期と2段キャッシュのアイディアは秀逸。


特徴
・key/valueインターフェイス
・ディスクキャッシュ、メモリキャッシュの2つから構成される (*)
・GCDを使った非同期な動作(保存と取り出し)
・メモリキャッシュはメモリ不足やバックグラウンド移行時に自身をクリアする
・APIは同期・非同期の両方が用意されている
・指定日時以前のキャッシュを消すことができる(trimToDate:)
・iOS, OSX 両方で使える

*...ソースをざっと読んだ限りでは、両方へ書き込み、取り出しの時にはメモリキャッシュ→ディスクキャッシュ順で取得。2段構え!


使い方はこんな感じ。保存は非同期。時間がかかってもブロックされない。
UIImage *image = [[UIImage alloc] initWithData:data scale:[[UIScreen mainScreen] scale]];
[[TMCache sharedCache] setObject:image forKey:@"image" block:nil]; // returns immediately

取り出しはblocksで。
[[TMCache sharedCache] objectForKey:@"image"
                              block:^(TMCache *cache, NSString *key, id object) {
                                  UIImage *image = (UIImage *)object;
                                  NSLog(@"image scale: %f", image.scale);
                              }];
同期メソッドも用意されている。

- - - -
このライブラリはモダンでかなりいい感じ。キャッシュが非同期って言われてみれば目からウロコだった。メモリとディスク両方を使うのもユニークでいいアイディア。こうなると今までのキャッシュライブラリが古く見えてくるなー。ソースも簡潔で読みやすい(技術力ある)。


なおソースコードで気になった点が1つ。
id object = [strongSelf->_memoryCache objectForKey:key];
        if (!object) {
            object = [strongSelf->_diskCache objectForKey:key];
            [strongSelf->_memoryCache setObject:object forKey:key block:nil];
        }
strongSelf.memoryCacheではなく strongSelf->_memoryCache としているところ。ポインタアクセスでメンバ変数へアクセスしてる。単純に速度優先の為だけ???(ちなみにgetterはオーバライドされていない)。


(参考)以前書いたディスク保存型のキャッシュライブラリ。ARC非対応。

APIは同期のみ。条件が指定できてそれを超えたら勝手に消えていくところが便利。あと複数作れる(保存ディレクトリを分けられる)。
今回のライブラリと比べると古臭い...

0 件のコメント:

コメントを投稿