swift - Swift - 检查弱变量是否为 nil 或不是线程安全的?
问题描述
我有一个运行了很长时间并且我希望能够中断的进程。
func longProcess (shouldAbort: @escaping ()->Bool) {
// Runs a long loop and periodically checks shouldAbort(),
// returning early if shouldAbort() returns true
}
这是我的班级使用它:
class Example {
private var abortFlag: NSObject? = .init()
private var dispatchQueue: DispatchQueue = .init(label: "Example")
func startProcess () {
let shouldAbort: ()->Bool = { [weak abortFlag] in
return abortFlag == nil
}
dispatchQueue.async {
longProcess(shouldAbort: shouldAbort)
}
}
func abortProcess () {
self.abortFlag = nil
}
}
shouldAbort
闭包捕获对 的引用weak
,abortFlag
并检查该引用是指向nil
还是指向NSObject
。由于引用是weak
,如果原始NSObject
对象被释放,那么闭包捕获的引用将突然被释放,nil
并且闭包将开始返回true
。闭包将在longProcess
函数期间重复调用,这发生在 private 上dispatchQueue
。类上的abortProcess
方法Example
将从其他队列外部调用。如果有人在尝试执行检查以查看是否已被解除分配的同时调用abortProcess()
,从而解除分配怎么办?是否检查线程安全操作?abortFlag
longProcess
abortFlag
myWeakReference == nil
解决方案
您可以将分派任务创建为DispatchWorkItem
,它已经具有线程安全isCancelled
属性。然后,您可以将其分派DispatchWorkItem
到队列并让它定期检查其isCancelled
. 然后,您可以只cancel
发送您想要停止它的点。
或者,当试图将一些工作包装在一个对象中时,我们经常使用Operation
, 代替,它将任务很好地封装在自己的类中:
class SomeLongOperation: Operation {
override func main() {
// Runs a long loop and periodically checks `isCancelled`
while !isCancelled {
Thread.sleep(forTimeInterval: 0.1)
print("tick")
}
}
}
并创建队列并将操作添加到该队列:
let queue = OperationQueue()
let operation = SomeLongOperation()
queue.addOperation(operation)
并取消操作:
operation.cancel()
或者
queue.cancelAllOperations()
底线,无论您使用Operation
(坦率地说,将某些任务包装在自己的对象中的“首选”解决方案)还是自己滚动使用DispatchWorkItem
,这个想法都是一样的,即您不需要拥有自己的 state 属性来检测任务的取消。调度队列和操作队列都已经有了很好的机制来为你简化这个过程。
推荐阅读
- mongodb - 如何更新 mobgo db 中的集合
- android - WebView 仅适用于模拟器,不适用于设备
- android - 当我尝试在棉花糖版本上打开 MAP 时可能出现未处理的承诺拒绝
- powershell - Get-WindowsUpdateLog 流重定向
- ios - 当作为子视图添加到集合视图单元格时,滚动视图中的内容不可见
- python - Python Polyglot:如何防止连字符分隔属于一起的单词
- java - 有没有一种简单的方法可以将包含秒和毫秒的时间戳值更改为具有小时和分钟的时间戳值?
- java - 带有来自 firebase rt dababase 的数据的 TextView 在屏幕上消失 - 第二个问题
- python - 为什么这个脚本在 Idle 中运行,而不是在 Jupyter Notebook 中运行?
- asp.net-core - .netcore webapi 调试暂停