我正在开发的应用程序会定期从应用程序服务器刷新其本地数据缓存(10多个请求,每个请求都需要相当长时间)。为了不阻塞UI线程,我目前将这些请求异步运行。由于这些请求确实需要一段时间来处理并加载到核心数据中,因此我想利用
在将所有请求添加到操作队列之后,我使用
beginBackgroundTaskWithExpirationHandler
和NSOperationQueue
的依赖操作行为。在将所有请求添加到操作队列之后,我使用
waitUntilAllOperationsAreFinished
来阻塞直到所有操作完成(这不在主线程上)。我在原型中看到的问题是,当我运行应用程序并立即将其转到后台(按下home按钮)时,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
我做错了什么?
谢谢
waitUntilAllOperationsAreFinished
作为一种屏障/门,一旦通过该门,执行完成操作(在这种情况下,将所有下载的数据加载到Core Data中)。您是建议我创建另一个操作,该操作依赖于所有其他操作,以执行该完成操作吗?从而避免甚至使用waitUntilAllOperationsAreFinished
的需要? - chinabuffetwaitUntilAllOperationsAreFinished
? - chinabuffet