NSOperationQueue
クラスのバックグラウンドをサポートするための有用な戦略を練り上げることにいくつか問題があります。NSOperation
特に、次のアクションを実行するがたくさんあります。
- Webからファイルをダウンロードする
- ファイルを解析する
- CoreDataにデータファイルをインポートする
操作はシリアルキューに挿入されます。操作が完了すると、次の操作を開始できます。
アプリがバックグラウンドに入ったときに操作を停止(または続行)する必要があります。これらの議論から(AFNetworkingにはバックグラウンドサポートがありますか?およびNSOperationsのキューとアプリケーション出口の処理)、操作をキャンセルし、isCancelled
各操作内でプロパティを使用するのが最善の方法だと思います。次に、操作のキーポイントをそのプロパティと照合して、アプリがバックグラウンドに入ったときに(実行中の操作の)実行の状態をロールバックできます。
バックグラウンドサポートを強調するAppleテンプレートに基づいて、どのように同様の状況を管理できますか?単に操作をキャンセルするか、現在の操作が完了するのを待つことはできますか?詳細についてはコメントを参照してください。
- (void)applicationDidEnterBackground:(UIApplication *)application
{
bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
// Do I have to call -cancelAllOperations or
// -waitUntilAllOperationsAreFinished or both?
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// What about here?
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
});
}
前もって感謝します。
編集
NSOperation
main
メソッドが以下のコードを実行する場合、キャンセルイベントへの応答パターンに従うことはどのように可能ですか?
- (void)main
{
// 1- download
// 2- parse
// 2.1 read file location
// 2.2 load into memory
// 3- import
// 3.1 fetch core data request
// 3.2 if data is not present, insert it (or update)
// 3.3 save data into persistent store coordinator
}
私が説明した各メソッドには、さまざまなステップが含まれています(ダウンロードを除く非アトミック操作)。したがって、キャンセルはこれらの各ステップ内で発生する可能性があります(事前定義されていない方法で)。isCancelled
各ステップの前にプロパティを確認できますか?これは機能しますか?
TammoFreeseの編集に基づいて編集2
編集コードの意味を理解しました。でも気になるのは次のとおりです。キャンセル要求(ユーザーはホームボタンを押すことができます)は実行中の任意の時点で発生する可能性があるmain
ため、単に戻ると、操作の状態が破損します。戻る前に状態をクリーンアップする必要がありますか?どう思いますか?
私が説明した問題は、同期操作(実行しているのと同じスレッド内で同期して実行される操作)を使用すると発生する可能性があります。たとえば、main
がファイルをダウンロードしていて(ダウンロードはを介して実行されます+sendSynchronousRequest:returningResponse:error
)、アプリがバックグラウンドに置かれている場合、どうなる可能性がありますか?そのような状況をどのように管理するのですか?
// download
if ([self isCancelled])
return;
// downloading here <-- here the app is put in background
もちろん、アプリをフォアグラウンドにすると、キャンセルされたので操作をやり直すと思います。言い換えれば、それはその状態を維持しないことを余儀なくされています。私が間違っている?