我在以下情况下挣扎,请求我,因为我试图尽可能清楚地解释这一点:
我有一个CoummintyOperation类,它是GroupOperation的子类。调用CommuityOperation并将其添加到NSOperationQueue。 CommunityOperation反过来调用了一大堆NSOperations,它们也是GroupOperation的子句,反过来又在其中调用NSoperations。 我已经在CommunityOperation类中添加了GroupOperations的依赖项。 我正在处理的问题是如果嵌套操作失败,我需要在CommunityOperations类中取消所有NSOperations,但是我无法访问为添加CommunityOperation而调用cancelAllOperations方法的operationQueue
任何人都可以帮我解释如何调用此方法,取消此类中的所有操作(以及所有嵌套操作)并向用户显示错误消息。
提前致谢
以下是帮助解释我的问题的示例代码: CommunityOperation从另一个类(不包括在内)中放入一个operationQueue
public class CommunityOperation: GroupOperation {
var updateOperation: UpdateOperation!
var menuOperation: MenuOperation!
var coreDataSaveOperation: CoreDataSaveOperation!
var hasErrors = false
public init() {
super.init(operations: [])
updateOperation = UpdateOperation()
menuOperation = MenuOperation()
coreDataSaveOperation = CoreDataSaveOperation()
coreDataSaveOperation.addDependencies([updateOperation, menuOperation])
self.addOperation(updateOperation)
self.addOperation(menuOperation)
self.addOperation(coreDataSaveOperation)
}
}
MenuOperation类,其中也包含嵌套操作:
class UpdateMenuOperation: GroupOperation {
let downloadGroupsOperation: DownloadGroupsOperation
let downloadMembersOperation: DownloadMembersOperation
init() {
downloadGroupsOperation = DownloadGroupsOperation()
downloadMembersOperation = DownloadMembersOperation(])
super.init(operations: [downloadGroupsOperation,
downloadMembersOperation
])
}
}
DownloadGroupOperation类又是GroupOperation的子类。它有2个操作 - 第一个下载数据,第二个解析数据:
class DownloadTopGroupsOperation: GroupOperation {
let downloadOperation: DownloadOperation
let importTopGroupsOperation: ImportOperation
init() {
downloadOperation = DownloadOperation()
importOperation = ImportOperation()
importOperation.addDependency(downloadOperation)
importOperation.addCondition(NoCancelledDependencies())
super.init(operations: [downloadOperation, importOperation])
}
}
最后(哇)DownloadOperation类使用NSURLSession和方法downloadTaskWithURL
,它在这个方法的完成处理程序中,如果出现错误,我想在主operatioQueue上调用cancelAllOperations退回:
class DownloadOperation: GroupOperation {
init() {
super.init(operations: [])
if self.cancelled {
return
}
let task = session.downloadTaskWithURL(url) { [weak self] url, response, error in
self?.downloadFinished(url, response: response as? NSHTTPURLResponse, error: error)
}
}
func downloadFinished(url: NSURL?, response: NSHTTPURLResponse?, error: NSError?) {
if error {
*cancel allOperations on queue*
}
}
}
答案 0 :(得分:0)
它应该以一种不同的方式工作。我会在每次isCancelled
执行结束时检查GroupOperation
中的NSOperation
。如果操作被取消,则取消当前GroupOperation
,依此类推。最后,您的CommunityOperation
也应该被取消。
以下是建议解决方案的粗略实施:
extension GroupOperation {
func addCancellationObservers() {
self.operations.forEach() { $0.willCancelObservers.append() { [unowned self] operation, errors in
self.cancel() // cancel the group operation. will force it to cancel all child operations
}
}
}
}
然后从您拥有的每个群组操作的addCancellationObservers
方法中调用init
。
答案 1 :(得分:0)
如果您使用Apple的示例代码(或https://github.com/danthorpe/Operations这是该项目的演变),您可以通过将条件附加到具有依赖项的操作来对其进行排序。
以下是您的顶级GroupOperation
init() {
updateOperation = UpdateOperation()
menuOperation = MenuOperation()
coreDataSaveOperation = CoreDataSaveOperation()
coreDataSaveOperation.addDependencies([updateOperation, menuOperation])
// Attach a condition to ensure that all dependencies succeeded
coreDataSaveOperation.addCondition(NoFailedDependenciesCondition())
super.init(operations: [updateOperation, menuOperation, coreDataSaveOperation])
}
要解释这里发生的事情...... NSOperation
没有“失败”的概念。操作总是“完成”但是它们是成功完成还是失败并不会影响NSOperation
依赖项的工作方式。
换句话说,无论这些依赖项是否成功,操作都将在所有依赖项完成时就绪。这是因为“成功”和“失败”是子类必须定义的东西。 Operation
(NSOperation
子类)通过完成而没有任何错误来定义成功。
要处理此问题,请添加一个条件,确保没有依赖项必须失败。在操作中,这个条件被重命名以使其更清晰。但是,这个概念也存在于Apple示例代码中。