从 iOS13 开始,可以监控OperationQueue
使用progress
属性的进度。该文档指出,在跟踪进度时,只有不覆盖start()
计数的操作。但是,异步操作必须根据文档覆盖start()
而不是调用。super()
这是否意味着asynchronous
操作和progress
互斥(即只有同步操作可以与进度一起使用)?如果是这样的话,这似乎是一个巨大的限制。
在我自己的项目中,我删除了我的覆盖,start()
并且一切似乎isFinished
都可以正常工作(例如,依赖关系仅在我的异步操作基类内部设置为true
依赖操作时才启动)。但是,这似乎有风险,因为Operation
明确声明要覆盖start()
.
想法?
文献参考:
https://developer.apple.com/documentation/foundation/operationqueue/3172535-progress
默认情况下,OperationQueue 在设置 totalUnitCount 之前不会报告进度。当设置了 totalUnitCount 时,队列开始报告进度。对于在 main() 结束时完成的操作,队列中的每个操作都会为队列的整体进度贡献一个完成单位。覆盖 start() 且不调用 super 的操作不会影响队列的进度。
https://developer.apple.com/documentation/foundation/operation/1416837-start
如果您正在实现并发操作,则必须覆盖此方法并使用它来启动您的操作。您的自定义实现不得在任何时候调用 super。除了为您的任务配置执行环境之外,您对该方法的实现还必须跟踪操作的状态并提供适当的状态转换。
更新:我最终放弃了我AysncOperation
的一个简单SyncOperation
的等待直到finish()
被调用(使用信号量)。
/// A synchronous operation that automatically waits until `finish()` is called.
open class SyncOperation: Operation {
private let waiter = DispatchSemaphore(value: 0)
/// Calls `work()` and waits until `finish()` is called.
public final override func main() {
work()
waiter.wait()
}
/// The work of the operation. Subclasses must override this function and call `finish()` when their work is done.
open func work() {
preconditionFailure("Subclasses must override `work()` and call `finish()`")
}
/// Finishes the operation.
///
/// The work of the operation must be completed when called. Failing to call `finish()` is a programmer error.
final public func finish() {
waiter.signal()
}
}