[NSOperationQueue currentQueue]
是否等同于[NSThread currentThread]
或NSOperation
?
我有一个相当复杂的域模型,其中繁重的处理发生在调用堆栈的深层次。为了及时取消操作,我需要将NSOperation
作为参数传递给每个方法,直到我想要中断更长时间运行的循环。使用线程我可以使用[[NSThread currentThread] isCancelled]
所以如果有一个NSOperation的等价物似乎很方便,不幸的是只有看似无用的[NSOperationQueue currentQueue]
。
答案 0 :(得分:7)
在swift中提供了一个返回正在运行的操作的扩展
extension NSOperationQueue {
public var runningOperations: [NSOperation] {
return operations.filter {$0.executing && !$0.finished && !$0.cancelled}
}
}
然后你可以拿起第一个
if let operation = aQueue.runningOperations.first {}
答案 1 :(得分:4)
不,没有方法可以找到当前正在执行的操作。
解决问题的两种方法:
操作是对象。如果你需要对象A与对象B交谈,你需要安排A来引用B。有很多方法可以做到这一点。一种方法是将操作传递给需要了解它的每个对象。另一种是使用授权。第三个是使操作成为传递给每个方法或函数的更大“上下文”的一部分。如果您发现需要将一个对象的引用传递给其他几个对象,只是为了将它引导到最终将使用它的对象,那么您应该考虑重新安排代码。
让“重吊”方法返回一些传递给调用链的值。您不一定需要使用繁重的方法来调用[currentOperation cancel]
来实现目标。实际上,最好让它返回一些值,操作将理解为“工作已完成,现在停止”,因为它可以检查返回值并立即退出而不必在调用-isCancelled
时调用一段时间,看看它是否被取消。
答案 2 :(得分:3)
这不是一个好主意。操作通常由队列取消。在操作的main()方法中,你可以定期检查self是否被取消(例如,每次n遍历一个循环,或者在每个主要命令块的开头),如果是,则中止。
要响应取消(例如,某些UI元素与操作或队列的状态相关联),您可以使用键值观察(KVO)让您的控制器观察操作的启动,完成和取消属性(根据需要) ,然后在更新这些键时设置UI的状态(始终在主线程上)。根据JeremyP的评论,重要的是要注意来自操作线程的KVO通知和UI(几乎)总是应该在主线程上进行操作,因此您需要使用-performSelectorOnMainThread ...方法当您收到状态更改KVO关于您的操作的注释时更新您的实际用户界面。
你真的想做什么?也就是说,为什么您觉得应用程序的其他部分需要直接了解当前的操作?
答案 3 :(得分:1)
您可以将当前操作存储在线程字典中。请记住在退出之前摆脱它。如果您创建了对象,则可以安全地使用线程dict。
答案 4 :(得分:1)
您可以组合使用[NSOperationQueue currentQueue]& [NSThread currentThread]来实现这一目标。
基本上,您需要遍历currentQueue上的操作并找到在currentThread上运行的操作。
NSOperation不提供对其运行的线程的访问权限,因此您需要自己添加该属性并进行分配。
你可能已经在继承NSOperation并提供一个main,所以在该子类中添加一个'thread'属性:
@interface MyOperation : NSOperation
@property(nonatomic,strong) NSThread *thread ;
@end
然后,在'main'中将当前线程分配给该属性
myOperation.thread = [NSThread currentThread]
然后您可以添加'currentOperation'方法:
+(MyOperation *)currentOperation
{
NSOperationQueue *opQueue = [NSOperationQueue currentQueue] ;
NSThread *currentThread = [NSThread currentThread] ;
for( MyOperation *op in opQueue.operations ) {
if( [op isExecuting] && [op respondsToSelector:@selector(thread)] ) {
if( op.thread == currentThread ) {
return ( op ) ;
}
}
}
}
return nil ;
}
答案 5 :(得分:0)
您如何知道要取消哪项操作? 当你到达想要取消的点时,只需调用[myQueue operations]并完成操作,直到找到你想要取消的操作。我想如果你有数百万次操作(或数千次),这可能行不通。
[myQueue operations]是线程安全的 - Queue内容的快照。您可以随意潜水,非常快速取消。
另一种方式: NSOperationQueue不是单身人士,所以你可以创建一个Q就可以说200个工作,然后通过获取Q并取消全部取消全部20个。将Q存储在主线程的字典中,然后您可以从dict中获取要取消的作业并将其全部取消。即你有1000种操作,并且在代码中你意识到你不需要某项任务,你就得到那种Q,并查看它取消的工作。