Amazon Campaign

2012年10月20日土曜日

UIActivityIndicatorView の実装まとめ

iPhoneアプリにおける定番のインジケーター、いわゆる「考え中」アイコンを実装するにあたり、いくつかポイントがあったのでまとめておきます。

UIKitにインジケーターを表現する"UIActivityIndicatorView"があるので、「このViewを表示してあげるだけでいーのね」と思ったら、とんでもない。以下を考慮した実装が必要です。

  • Viewの実装
  • 別スレッドで処理
  • コールバック
  • リリースタイミング

Viewの実装

まずは UIActivityIndicatorView を生成します。これは当然ですね。

UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
indicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhite;
[indicator setCenter:CGPointMake(self.bounds.size.width / 2, self.bounds.size.height / 2)];

別スレッドで処理

インジケーターを表示したいってことは、当何らかの処理をさせたい訳なんですが、同一スレッド上で
インジケーター生成 → インジケーターViewを追加 → やりたい処理 → インジケーターView削除
ではダメなんです。
インジケーターViewを追加した状態でViewControllerの処理をいったん抜けて、端末上で描画処理まで進めてあげなければいけません。だから別スレッドで「やりたい処理」を実行させないとダメなんです。
そこで、メソッド"performSelectorInBackground"で別スレッドを立てて、引数のselectorで「やりたい処理」を呼び出してあげます。

// インジケーターView追加
[self.navigationController.view addSubview:self.indicator];

// インジケーター再生
[self.indicator startAnimating];

// 別スレッドで処理
[self performSelectorInBackground:@selector(othreProcess) withObject:nil];
[self.window makeKeyAndVisible];


コールバック

続いて、別スレッドでの「やりたい処理」が終わったら、メインスレッドへ処理が終わった旨を通知(コールバック)し、インジケーターの表示を止めてあげます。ここでは"hideIndicator"というメソッドを呼び出しています。
また、別スレッドを立てる場合は新たなスレッドでのautoreleaseを格納する"NSAutoreleasePool"を宣言してあげる必要があるようです。

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

//
//  ここでやりたい処理を実行。
//

[pool release];
 
// 終了処理をメインスレッドへ通知
[self performSelectorOnMainThread:@selector(hideIndicator) withObject:nil waitUntilDone:NO];
-(void)hideIndicator {
 [self.indicator removeFromSuperview];
 [self.indicator stopAnimating];
}


リリースタイミング

最後に、別スレッドで実行した「やりたい処理」で、何らかのインスタンスを生成する場合、慣習的に "autorelease" を明示していると、先ほどの"NSAutoreleasePool"のreleaseメソッドを呼んだタイミングで開放されてしまいます。
ですので、autorelease とせずに、適切なタイミングを考慮して "release" を呼んであげる必要があります。

なんかインジケーターってよく見るので、もっと簡単、簡潔に実装できるもんだと思っていましたが、結構手間ですね。UIKit ってやつは。。。

0 件のコメント:

コメントを投稿

Amazon_ad