我在阐述支持NSOperationQueue
类的背景的有用策略时遇到了一些问题。特别是,我有一堆NSOperation
s表示执行以下操作:NSOperationQueue和背景支持
- 从网络
- 解析文件
- 导入数据文件中的核心数据
的下载文件操作被插入到串行队列中。一旦操作完成,下一个可以开始。
我需要在应用程序进入后台时停止(或继续)操作。从这些讨论(Does AFNetworking have backgrounding support?和Queue of NSOperations and handling application exit)我看到最好的办法是取消操作并在每个操作中使用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
属性吗?这是否工作?基于Tammo福瑞斯”编辑
我明白你的意思是你编辑代码
编辑2。但我担心的是以下内容。取消请求(用户可以按主页按钮)可能会在main
执行过程中的任何位置发生,所以,如果我简单地返回,操作状态将被破坏。我需要在返回之前清理它的状态吗?你怎么看?
当我使用同步操作(在同一个线程内以同步方式执行的操作)时,我描述的问题可能会发生。例如,如果main
正在下载文件(通过+sendSynchronousRequest:returningResponse:error
执行下载),并且该应用程序置于后台,则会发生什么情况?如何管理这种情况?
// download
if ([self isCancelled])
return;
// downloading here <-- here the app is put in background
很明显,我认为当应用程序被放在前台时,操作会再次运行,因为它已被取消。换句话说,它被迫不保持其状态。我错了吗?
+1您的回复。关于你的理解,是的,这是正确的。但是,你认为还有其他解决方案可以实现吗?在一个操作的* main *中,我执行三个不同的任务。那么,怎样才能以正确的方式取消手术呢?关于你的回复的第二部分,我无法理解*如果这个块被调用,我们的背景时间通常是10分钟 几乎超过*评论。你能说一下吗?最后,第二部分(* dispatch_async *)执行什么?你为什么要检索主线程?感谢您的支持。 –
Hi @flexaddicted,要以正确的方式取消操作,您应该对文档中描述的取消事件做出反应:http://developer.apple.com/library/mac/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationObjects/ OperationObjects.html#// apple_ref/doc/uid/TP40008091-CH101-SW24。 –
关于第二部分:如果您使用iOS注册后台任务,通常会让您花10分钟完成它。当你的任务完成时,通过调用'-endBackgroundTask:'让iOS知道。假设您的操作在10分钟后仍未完成。只有在这种情况下,iOS才会调用过期处理程序块给你一个清理机会。如果你不在该块中调用'-endBackgroundTask:',你的应用将会被杀死,因为它行为不当。你必须平衡对'-beginBackgroundTaskWithExpirationHandler:'和'-endBackgroundTask:'的调用。 –