在我的应用程序中,当用户关闭应用程序(即它进入后台)时,我正在将数据与服务器同步。此过程大约需要一分钟,并且涉及到服务器上传数据的各种调用,因此我选择将其作为后台线程执行。
- (void)applicationDidEnterBackground:(UIApplication *)application {
bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[asynchronousAPIController processQueueOrWaitWithIsBackgroundSync:true];
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
});
}
除非用户在此同步期间(即在第一分钟内)重新进入前景,否则此工作正常。我想要的是让后台同步终止完成 - 即使它在同步的中途也会停止同步。当应用程序接下来进入后台时,它可以从头开始重启整个过程,没问题。
我尝试过使用它:
- (void)applicationWillEnterForeground:(UIApplication *)application {
if (bgTask != UIBackgroundTaskInvalid) {
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
}
但它并没有停止同步 - 只是继续前进。几乎就像它一旦开始它就继续前进。
我怀疑这可能是因为控制同步的对象是一个单身人士 - 也就是说,它不是一个可以被摧毁的类对象,而是一个单身人士,因此可能因此而活着。这会有所作为吗?
或者我只是做错了什么?
任何建议,非常感谢。
答案 0 :(得分:4)
您需要在NSOperation中完成后台工作。我将创建一个NSBlockOperation并将其添加到NSOperationQueue。这样就可以自动生成后台线程。对于复杂的操作,创建一个NSOperation子类。
在NSOperation代码内部检查操作是否定期取消(例如在for循环内),如果是,则退出代码块(在for循环中:if ([operation isCanceled]) break;
)。
在applicationWillEnterForeground中只需取消操作即可。