こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

ios/バックグラウンドからループを呼び出したとき

objective-cで、バックグラウンドに入ったときに、for文のあるメソッドを呼び出したところ、ループが終わると画面が黒くなってしまいます。落ちてはいないです。どうなっているんでしょうか?
以下が実際のソースです

- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(test)
name:UIApplicationDidEnterBackgroundNotification
object:nil];
}

-(void)test{
for (int i; i < 5; i++) {
NSLog(@"%d", i);
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.0f]];
}
}

投稿日時 - 2014-08-21 19:54:34

QNo.8725265

困ってます

質問者が選んだベストアンサー

No.1です。

> やりたいことは、
> ・バックグラウンドに入ってから1秒ごとにローカル通知をおくる
> ・5秒後にタイマーを止めるメソッドを呼ぶ
> ・5秒以内にフォアグラウンドになった場合はタイマーを止めない

「1秒ごとにローカル通知」というのは、UILocalNotificationを使う
ってことじゃなくて、単にバックグラウンドで1秒間隔のタイマーを
起動したいということでしょうか?

アプリがバックグランドに入って実行中断する前に少しだけアプリを
動かしたいということであれば、
Task Completion(beginBackgroundTaskWithExpirationHandler)
を使えばよいと思います。
(参考)
http://cocoadays.blogspot.jp/2011/04/ios-task-completion.html

これを使えば、最大3分バックグラウンドでアプリの実行を継続できます。
(以前は最大10分でしたが、iOS7からは最大3分になりました。)

上記サイトのサンプルは、GCDを使って別スレッドで実行している
プログラムを継続するというちょっと難しいサンプルになっていますが、
NSTimerで1秒ごとにタイマ通知をもらって動くだけという場合でも
beginBackgroundTaskWithExpirationHandlerをやれば
最大3分間タイマー通知を受け続けることができます。

投稿日時 - 2014-08-23 10:39:26

お礼

ご丁寧にありがとうございます!おかげで無事できそうです!

投稿日時 - 2014-08-24 21:39:23

このQ&Aは役に立ちましたか?

9人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.1

> バックグラウンドに入ったときに、for文のあるメソッドを呼び出したところ、ループが終わると画面が黒くなってしまいます。

質問のコードをそのままコピペして実行してみたところ、
ホームボタンを押してバックグラウンドに入ったら、
アプリは表示されなくなりホーム画面が表示されました。
そのままNSRunLoop呼び出しの繰り返しが終わっても画面は
ホーム画面のままでした。特に画面は黒くなりません。

ただ、NSRunLoop呼び出しの繰り返し中に、アプリのアイコンを
タップしてフォアグラウンドに戻したら、アプリの画面が復帰し
NSRunLoop呼び出し終了後に画面が黒くなりました。
この現象のことを聞いているんでょうか?

画面が黒くなる原因は正確には説明できませんが
この場合、applicationDidEnterBackground処理の途中に
aplicationWillResignActiveやapplicationDidBecomeActive
が動作してしまいます。(この2つのイベントのログを入れれば
その動作タイミングがよくわかります。)
このため、applicationDidEnterBackground処理中に
NSRunLoop呼び出しされたらどうなるかわからない
(Appleも動作を保証していない)というところだろう
と推測します。

何がしたいのかよくわかりませんが、applicationDidEnterBackground
処理の中でNSRunLoopを呼び出すのはやめた方がよいと思います。
なぜそれが必要なのかを説明すれば、何か代替案のアドバイスが
できるかもしれません。

投稿日時 - 2014-08-21 23:14:28

補足

Lchan0211bさん
そのとおりです!バックグラウンドからフォアグラウンドに戻ったときに黒くなります!説明不足で申し訳ないです…

やりたいことは、
・バックグラウンドに入ってから1秒ごとにローカル通知をおくる
・5秒後にタイマーを止めるメソッドを呼ぶ
・5秒以内にフォアグラウンドになった場合はタイマーを止めない
です。うまく説明できてますかね…

投稿日時 - 2014-08-22 23:01:20