2013年9月27日金曜日

applicationDidBecomeActive が呼ばれた時に ViewController のメソッドを呼ぶ

CoreLocation を使うアプリを作っているが、アプリを閉じる→再開の繰り返しをすると、数回に一度アプリが落ちる現象が出る。

Xcode のデバッガには、「com.apple.CoreLocation.ConnectionClient」と出て落ちているから当たりは間違い無いとは思うが、原因が分からない。

処理としては、CoreLocation の開始を viewDidLoad で行ってた。
そして、バックグラウンドからの復帰時に CoreLocation の開始が行われていないため、無理矢理 applicationDidBecomeActive で、viewController の viewDidLoad を呼ぶようにしていた。
つまり、連続での CoreLocation のスタートをかけているのがまずいのでは?と思い、この部分にあたりを付けてみた。

さて、この場合 1 回だけ Location をスタートするにはどうすれば?

NSLog を張り巡らして見ていると、真っ新からの起動であろうと、バックグラウンドからの起動であろうと、applicationDidBecomeActive を通る事が分かった(公式のドキュメントにも書いてある)。

要するに、applicationDidBecomeActive で、Location の開始処理を行えば良いのだが、applicationDidBecomeActive は、AppDelegate でのメソッドのため処理の関係上 Location のスタートを開始するには不適切だった。
そこで、applicationDidBecomeActive に入ったときに ViewController のメソッドが発行でき、そのメソッドで Location の開始が出来れば良いと思い処理をする方法を調べたところ、以下の実現方法があったので採用した。

これは通知処理を使って、applicationDidBecomeActive が発生したときに発火するメソッドを登録すると言う物。
この登録を viewDidLoad で行う。
当然、いままで有った Location スタートは削除する。
    -(void) viewDidLoad {
        ...
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(applicationDidBecomeActive)
                                                     name:UIApplicationDidBecomeActiveNotification
                                                   object:nil];
        ...
    }
また、applicationDidBecomeActive 後に発動するメソッドを記述する。
ここに、Location のスタートをする処理を入れる。
    // applicationDidBecomeActive が呼ばれた時に実行する
    - (void)applicationDidBecomeActive {
        // CoreLocation 開始
        [_manager startUpdatingLocation];
    }

これで、立ち上げ→バックグラウンドの連続操作を繰り返してみたところ、アプリが落ちる事が無くなった(とはいえ、安心は出来ないので後日合間を見て検証をしてみる)。
他の遷移の場合を考えたらもう少し手間をかける必要は有ったが、取りかかりとしてはこの線で良かった。

0 件のコメント:

コメントを投稿