我想知道我的操作是否被取消或正常完成。这是我的代码片段:
class PacketReceiver {
private let m_executer = OperationQueue()
private var m_operation : Operation?
private func operationFinishedHandler()
{
if let op = m_operation {
if op.isCancelled {
print("Operation cancelled")
} else {
print("Operation finished OK \(op.isCancelled)")
}
}
}
func start()
{
let rxPacketOperation = PacketReceiverOperation()
rxPacketOperation.completionBlock = self.operationFinishedHandler
m_operation = rxPacketOperation
m_executer.addOperation(rxPacketOperation)
}
func cancel()
{
if let op = m_operation {
op.cancel()
}
}
func join()
{
if let op = m_operation {
print("is op cancelled = \(op.isCancelled)")
}
m_executer.waitUntilAllOperationsAreFinished()
if let op = m_operation {
print("is op cancelled = \(op.isCancelled)")
}
}
}
后来我有:
let packetReceiver = PacketReceiver()
packetReceiver.start()
packetReceiver.cancel()
packetReceiver.join()
[我看到join()
方法isCancelled
内部的属性设置为true。但是当我在完成的处理程序中检查它时,它是错误的。我想这是预期的行为。但是检查我的操作是否被取消的正确方法是什么?
这是我的操作课:
class PacketReceiverOperation : Operation {
private var m_packetData : String = ""
private let m_simDataProvider = SimDataProvider(okAttemptId : 2)
private let m_currentTimeProvider = CurrentTimeProvider()
private func prepareReceiver() {
m_packetData = ""
print("\(m_currentTimeProvider.getCurrentTimeAsString()) : prepare SIM receiver")
}
override func main() {
if isCancelled {
return
}
prepareReceiver()
if isCancelled {
return
}
var isPacketReceived = false
var isFirstChunkReceived = false
repeat {
if isCancelled {
return
}
if let chunkData = m_simDataProvider.getPacket() {
isFirstChunkReceived = true
m_packetData.append(";" + chunkData)
} else {
if isFirstChunkReceived {
isPacketReceived = true
}
}
} while isPacketReceived == false
}
}
[由于多种原因(尤其是缺少抢先取消和一般比赛条件),isCancelled
状态不是一种可靠的方式来知道您的Operation
子类是否成功完成。 (它告诉您是否尝试取消,但基本任务是否成功。)
由于这个原因,我很少使用内置的completionHandler
(没有参数),而是通常实现自己的自定义完成处理程序闭包,该闭包提供Result
(或其他任何东西)作为参数。这消除了所有歧义。
或者,在您的情况下,您可以将isPacketReceived
设置为操作的属性,而不是局部变量,然后您可以查看该值以确定是否完全接收到数据包,而不是isCancelled
。] >
您稍后说:
[我看到
completionHandler
完成后调用了join()
。是的,是的。
但是,join
根本就是一个同步方法,这有点令人担忧(即,您正在调用waitUntilAllOperationsAreFinished
)。操作队列的目的是让我们可以为可能耗时的任务采用异步模式,并将其从主线程中删除。在我们等待操作完成时阻塞(特别是如果您从主线程调用join
时)似乎无法达到目的。
我鼓励您采用异步模式,只需将您的操作添加到队列中,然后在其完成处理程序中启动所需的任何内容(无论是默认的还是您自己的)。