无法理解NSOperation& NSOperationQueue(快速)

时间:2015-08-21 22:35:14

标签: multithreading swift

我无法理解如何创建同步NSOperationQueue。 我创建了一个原型,基本上说:

  • 创建4个非常长或很短的操作来完成
  • 无论何时完成,都应按照队列中创建的顺序完成。

我的NSOperation课很简单:

class LGOperation : NSOperation
{
    private var operation: () -> ()
    init(operation: () -> ())
    {
        self.operation = operation
    }

    override func main()
    {
        if self.cancelled {
            return
        }
        operation()
    }
}

我的测试课也很简单:

class LGOperationTest
{

    class func downloadImage(url: String)
    {
        // This is a simple AFHTTPRequestOperation for the image
        LGImageHelper.downloadImageWithUrl(url, complete: { (image: AnyObject?) in
            println("downloaded \(url)")
        })
    }

    class func test()
    {
        var queue = NSOperationQueue.mainQueue()
        queue.maxConcurrentOperationCount = 1
        var op1 = LGOperation(operation: { self.downloadImage("http://www.toysrus.com/graphics/tru_prod_images/Animal-Planet-T-Rex---Grey--pTRU1-2909995dt.jpg") })

        var op2 = LGOperation(operation: { println("OPERATION 2") })

        var op3 = LGOperation(operation: { self.downloadImage("http://www.badassoftheweek.com/trex.jpg") })

        var op4 = LGOperation(operation: { println("OPERATION 3") })
        var ops: [NSOperation] = [op1, op2, op3, op4]
        op2.addDependency(op1)
        op3.addDependency(op2)
        op4.addDependency(op3)
        op4.completionBlock = {
            println("finished op 4")
        }

        queue.addOperation(op1)
        queue.addOperation(op2)
        queue.addOperation(op3)
        queue.addOperation(op4)     
        println("DONE") 
    }
}

所以我希望这里的操作按顺序完成,而输出是:

为什么我不能使Web请求与其他代码同步启动? (我知道我可以使用完成块并链接它们但是我想知道如何使用NSOperation来实现它)

1 个答案:

答案 0 :(得分:0)

操作队列用于调度异步操作,主要是这些操作可能会长时间运行,并且您不希望阻止当前(通常是UI)线程。阻止UI线程会导致UI无响应。

当您创建4个操作时,它们完成时是执行操作的因素。在您的情况下,您的操作正在执行println(速度非常快),并且您有从互联网下载的操作(速度非常慢)。

操作队列的重点是允许您异步触发这些操作,并且每当操作完成时,触发完成处理程序。

换句话说,你无法控制序列。

如果您想控制序列,我建议您执行以下操作:

  1. 开始操作1
  2. 在操作1的完成处理程序中,启动操作2
  3. 在操作2的完成处理程序中,启动操作3
  4. 在操作3的完成处理程序中,启动操作4
  5. 通过这种方式,您仍然可以获得操作队列的好处(您不会阻止UI线程),并且您可以按顺序链接操作。