そもそもUIActivityIndicatorViewを使いたいのは、処理のかかる作業をさせたいわけだ
id:uedam0322:20090206 にUIActivityIndicatorViewについて記載がある
UIActivityIndicatorViewをくるくる回すには別スレッドを立ち上げ、そちらで重い処理を行い、
メインスレッドではくるくるを表示させる。
ところが別スレッドで重い処理をさせる場合でも
- 裏でthread safeでないUIKitが動いているから、その別スレッドではthread safeなことしかできない=Core Data系はかなり全滅
- せいぜい使えるのはFoundation, それもファイル入出力系はいまのところダメ, 使うのならlock/@synchronizedしてね
- UIKitをそのThreadで使いたければperformSelectorOnMainThread を使ってmain threadで処理させる
- もちろん別スレッドになっているのでAutorelease Poolを別にたてないとメモリリークしまくり
結局こんなコードにしましたが大丈夫かな?
-(void)someJobFinish { [activityView stopAnimating]; // 一応UIKitのAPIなのでThread外で.. UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Finished" message:someString delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; [alert release]; [someString release]; } -(void)someJob { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; int i; NSString *str; // このスレッド内ではThreading SafeなAPIしか使わないように for(i=0;i<100;i++) { // 重い処理のつもり str = [NSString stringWithFormat:@"%i",i]; } [NSThread sleepForTimeInterval:1.0]; @synchronized(self) { someString = [str retain]; // 戻す値をインスタンス変数に格納する } [self performSelectorOnMainThread:@selector(someJobFinish) withObject:nil waitUntilDone:NO]; [pool release]; // ゴミ掃除 [NSThread exit]; } -(IBAction)pressStart:(id)sender { // activityViewを回すボタンにリンクしてあります someString = nil; [activityView startAnimating]; [NSThread detachNewThreadSelector:@selector(someJob) toTarget:self withObject:nil]; }