0

サーバーに ping を実行する前に、以下のコードを使用してアプリにバックグラウンド プロセスのサポートを追加しました。

UIApplication *app = [UIApplication sharedApplication];
        bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
            [app endBackgroundTask:bgTask];
            bgTask = UIBackgroundTaskInvalid;
        }];
        if (!connection) {
            connection = [[NSURLConnection alloc] init];
        }
        (void)[connection initWithRequest:originalRequest delegate:self];

このコードが原因で、アプリケーションを 10 分以上バックグラウンド モードにしておくとクラッシュします。私の理解では、タスクをバックグラウンドで継続的に実行することを許可しないでください。各タスクに一定の時間間隔を設定する必要があります。しかし、それらを殺すための時間間隔を設定する方法がわかりません。

この問題を解決するためのいくつかの手順を提案してください。

4

1 に答える 1

1

ここにはいくつかの重要なポイントがあり、その多くはすでにコメントで取り上げられています。

まず、あなたが持っている時間はわかりません。経験的な値があります (iOS 7 では 10 分前、iOS 7 では 3 分) が、これらは保証されていません。特に、仕事をするために睡眠から目覚めた場合 (例: ジオフェンス アラート)、完全な時間を取得できず、最後の時間からの残り時間しか取得できない場合があります。時間をリセットする特定のアクションがあります (たとえば、iOS の一部のバージョンでは、GPS を使用して位置情報を取得するとタイマーがリセットされる場合があります)。

第二に、あなたはまだ仕事をしているから殺されているのではなく、まだ仕事をしていると OS に伝えたために殺されているのです。OS はネットワーク転送を気にしません。beginBackgroundTaskWithExpirationHandler を気にします。

これは、「許可された時間を超えてアクティブなアサーションがあります」と表示されるクラッシュ レポートから確認できます。

これには 3 つの理由が考えられます。
1) OS は完了ハンドラーを呼び出しましたが、endBackgroundTask を時間内に呼び出しませんでした。バックグラウンド ハンドラーが呼び出される時間はあまりありませんが、これが問題であるとは思えません。コードはかなりコンパクトです。

2) OS は完了ハンドラーを呼び出しましたが、endBackgroundTask をまったく呼び出しませんでした。これを行うコードを継承しました。通常の理由は、コードが再入可能ではなく、2 回呼び出されることです。bgtask は 2 番目の値に更新されるため、完了ハンドラが起動すると、bgtask は一方のタスクで 2 回終了し、もう一方のタスクでは決して終了しません。繰り返しますが、あなたは安全だと思います。これは通常、メンバー変数の問題です。あなたの場合、bgtask をブロックでコピーする必要があります。

3) OS がバックグラウンド ハンドラーを呼び出さなかった (可能性は低いですが、iOS 7 について根拠のない疑惑がいくつかあります)。

バックグラウンド実行の問題ではない次の可能性は、実際にはクラッシュしていないことです。Xcode から切断してアプリを実行し、クラッシュ レポートが生成されるかどうかを確認します。そうでない場合は、メモリ不足のために排出されている可能性があります。バックグラウンドの問題でこれが本当に長すぎる場合は、例外コードが 0x0badfood であることがわかります。悪い食べ物はウォッチドッグ タイマーを怒らせます。

バックグラウンド プロセスは、静かにイジェクトされたときにバックグラウンド アプリから削除されていたと思いますが、ユーザーがそれらをフォアグラウンドに持ってくると、OS はそれらをスクリーンショットに置き換え、新たに開始します。

于 2013-10-28T09:50:58.273 に答える