私が取り組んでいるアプリは、アプリケーション サーバーからのローカル データ キャッシュを定期的に更新します (10 件以上のリクエストで、それぞれにかなりの時間がかかります)。現在、UI スレッドをブロックしないように、これらのリクエストを非同期で実行しています。これらのリクエストは、処理してコア データにロードするのに時間がかかるためbeginBackgroundTaskWithExpirationHandler
、NSOperationQueue
.
すべてのリクエストを操作キューに追加した後、waitUntilAllOperationsAreFinished
すべての操作が完了するまでブロックするために使用します (これはメイン スレッドではありません)。私のプロトタイプで見られる問題は、アプリを実行してすぐにバックグラウンドにすると (ホームボタンを押す)、waitUntilAllOperationsAreFinished
すべての操作が完了した後でもブロックされたままになることです...しかし、アプリを再度開くとすぐに、ハンドラーが終了します。アプリを実行してフォアグラウンドのままにしておくと、すべて正常に終了します。この動作は、実際のアプリでは常に発生するとは限りませんが、以下のコード例では次のように見えます。
#import "ViewController.h"
@interface ViewController ()
@property (assign, nonatomic) UIBackgroundTaskIdentifier task;
@property (strong, nonatomic) NSOperationQueue *queue;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self performSelectorInBackground:@selector(queueItUp) withObject:nil];
}
- (void)queueItUp {
UIApplication *application = [UIApplication sharedApplication];
self.queue = [[NSOperationQueue alloc] init];
self.task = [application beginBackgroundTaskWithExpirationHandler:^{
NSLog(@"Took too long!");
[self.queue cancelAllOperations];
[application endBackgroundTask:self.task];
self.task = UIBackgroundTaskInvalid;
}];
for (int i = 0; i < 5; i++) {
[self.queue addOperationWithBlock:^{
[NSThread sleepForTimeInterval:3];
NSLog(@"Finished operation.");
}];
}
NSLog(@"Waiting until all operations are finished.");
[self.queue waitUntilAllOperationsAreFinished];
[application endBackgroundTask:self.task];
self.task = UIBackgroundTaskInvalid;
NSLog(@"All done :)");
}
@end
私は何を間違っていますか?
ありがとう