URL の分かっているALAssetをキューの流れを崩さずに取得する方法

iOS4でiOS SDKにも追加されたBlocksは、いまでは多くのiOS標準ライブラリで使われています。バックグラウンドで作業を行わせて、作業が終わったときのコールバックや結果を取得する事が出来ます。確かに、スムーズなUIを実現するのに便利なのですが、ときどき、プログラムの流れを崩したくないので、順序立てて動作してほしいと思うときがありますね。例えば、ALAssetで画像を取得するときも、画像を順番にアップロードしたいなどの要望があります。そのときにALAssetをsyncronizeに取得するメソッドを書きました。


ポイントがいくつかあります。

  • Dispatch Semaphore

  • エキスパートObjective-Cプログラミングの説明を引用すると、

    Dispatch Semaphore は、マルチスレッドプログラミングでは計数型セマフォとして知られるカウンタを持ったセマフォです。セマフォとは、交通機関における手旗信号です。通ってよいときは手 旗信号を上げ、通ってはいけないときは手旗信号を下げる、という具合です。Dispatch Semaphore では、カウンタを使ってそれを実現しています。カウンタが 0 のときは待つ、カウンタが 1 以上の ときは 1 減算して待たずに進む、となっています。

    さすがに分かりやすいですね。つまり、dispatch_semaphore_signalを通るとdispatch_semaphore_waitで待っている部分が動き出すという事ですね。これをやる前は、NSRunloopで待たせていたのですが、メインスレッドがロックされてしまい、うまく待つ事が出来ませんでした。
    こちらの解決策を参照しました。iphone – Wait for assetForURL blocks to be completed – Stack Overflow

    これでAssetを同期的に取得する事が出来るので、

    ALAssetsLibrary * library = [[ALAssetsLibrary alloc] init];
    NSMutableArray* arrayURLString;
    [arrayURLString enumerateObjectsUsingBlock:^(NSString * obj, NSUInteger idx, BOOL *stop) {
    ALAsset* asset = [self.library getSyncAssetFromURL:[NSURL URLWithString:obj]];
    UIImage * image = asset.defaultRepresentation.fullResolutionImage;
    // image を使用する。
    }];

    のように、連続してAssetを使用する事が出来ます。

  • GCDオブジェクトのメモリ管理の振る舞い

  • 丁度、昨日今日で話題になっていた、GCDオブジェクトの振る舞い方の話しです。
    iOS6(ARC)でのGCDのメモリ管理 – blog.ishkawa.org

    何も触らないと、Deployment TargetがiOS6.0以降の場合、GCDのオブジェクト(ここではdispatch_semaphore_t)がオブジェクトとして振る舞います。(実行環境でなくて、デバッグ時の環境なので、実行時でOSのバージョンを見て動作を変える必要はないです。)しかし、OS_OBJECT_USE_OBJCコンパイル変数に0を設定すると、Deployment Targetが6.0でもGCDの変数はオブジェクトとして振る舞わないので、Releaseしてあげる必要があります。

    ですから、dispatch_semaphore_tを使う場合は、特に現在Deployment Targetが5の場合は、
    #if OS_OBJECT_USE_OBJC!=1
    dispatch_release(sema);
    #endif

    でチェックしておくと、後々DeploymentTargetを変えたときにも問題無くてよい感じですね。

    こんな感じで、普段よく使うBlocksも、色々便利に使う事が出来ますねという話しでした。

    4月4日発売予定の「iPhoneアプリ開発エキスパートガイド iOS 6対応」絶賛!予約中です。
    iPhoneアプリ開発エキスパートガイド iOS 6対応

「URL の分かっているALAssetをキューの流れを崩さずに取得する方法」への1件のフィードバック

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください