Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
iOS swift操作队列_Swift_Concurrency_Nsoperationqueue_Nsoperation_Operation - Fatal编程技术网

iOS swift操作队列

iOS swift操作队列,swift,concurrency,nsoperationqueue,nsoperation,operation,Swift,Concurrency,Nsoperationqueue,Nsoperation,Operation,我正在使用OperationQueue开发iOS应用程序。我已经创建了2个操作。操作2取决于操作1的完成。如果操作1正在运行,则操作2需要等待操作1完成。如果操作1未运行,则操作2应立即启动 它没有按预期工作,所以我正在操场上测试 class MyManager { var operationQueue: OperationQueue? var operation1: MyOperation? = nil var operation2:

我正在使用OperationQueue开发iOS应用程序。我已经创建了2个操作。操作2取决于操作1的完成。如果操作1正在运行,则操作2需要等待操作1完成。如果操作1未运行,则操作2应立即启动

它没有按预期工作,所以我正在操场上测试

    class MyManager {

        var operationQueue: OperationQueue?

        var operation1: MyOperation? = nil
        var operation2: MyOperation? = nil

        typealias completion = (_ serverError: String?) -> Void

        func talkWithServer(completion: completion?) {

            completion?("competed!")
        }

        func doOperation1() {

            cancelProcess()
            setup()

            guard let operation1 = self.operation1 else { return }
            operation1.codeToRun = {
                print("operation1 started")
                self.talkWithServer(completion: { (completion) in
                    print("operation1 completed")
                    operation1.markAsFinished()
                })
            }
            operationQueue?.addOperation(operation1)

        }


        func doOperation2() {
           self.operation2 = MyOperation()

            guard let operation2 = self.operation2 else { return }



            operation2.codeToRun = {
                print("operation2 started")
                self.talkWithServer(completion: { (completion) in
                    print("operation2 completed")
                    operation2.markAsFinished()
                })
            }

if let operation1 = self.operation1 {
            if operation1.isExecuting {
                operation2.addDependency(operation1)
                operation1.completionBlock = {
                    print("operation1.completionBlock")
                    self.operationQueue?.addOperation(operation2)
                }
            }
            } else  {
                operationQueue?.addOperation(operation2)
            }

        }


        func cancelProcess() {
            print("cancelAllOperations")
            operationQueue?.cancelAllOperations()
        }

        func setup() {
            print("setup Called")
            operationQueue?.cancelAllOperations()
            operationQueue = OperationQueue()
            operation1 = MyOperation()
            operation2 = MyOperation()
        }
    }


    class MyOperation: Operation {
        var codeToRun: (()->Void)?

        var _executing = false
        var _finished = false

        override internal(set) var isExecuting: Bool {
            get {
                return _executing
            }
            set {
                _executing = newValue

            }
        }

        override internal(set) var isFinished: Bool {
            get {
                return _finished
            }
            set {
                _finished = newValue
            }
        }

        override var isAsynchronous: Bool {
            return true
        }

        override func start() {
            isExecuting = true
            isFinished = false
            if let closure = self.codeToRun {
                closure()
            }
        }

        func markAsFinished() {
            self.isExecuting = false
            self.isFinished = true
            completionBlock?()
        }
    }

    let manager = MyManager()

    manager.doOperation1()
    manager.doOperation2()
我得到了结果

cancelAllOperations
setup Called
operation1 started
operation1 completed
operation1.completionBlock
预期是

cancelAllOperations
setup Called
operation1 started
operation1 completed
operation1.completionBlock
operation2 started
operation2 completed

我这里遗漏了什么吗?

我一直在看你的代码。我发现了一些东西:

弗斯特 这并不意味着operation2在operation1完成后运行,如果要执行此操作,可以为operation1添加完成闭包

第二 当你打电话的时候

doOperation2()
在该函数中,代码似乎从未在以下情况下执行:

guard let operation2 = self.operation2 else { return }
毕竟 看起来你想创建自己的轮子。我建议您学习一些关于GCD的知识,您可以在这里找到资源:


有两件事:

实施:
  • i执行
    i完成
    实施
    KVO
  • 修复操作2
  • 一旦设置了依赖项,
    operation2
    即使添加到队列中也不会启动,直到
    operation1
    完成
  • 检查内部是否取消了操作
下面不是实现
doOperation2
的理想方法,但它可以消除代码中的一些混乱。我将让您根据下面提到的设计部分来实现整个过程

func doOperation2() {

    self.operation2 = MyOperation()

    guard let operation2 = self.operation2 else {
        return
    }

    operation2.codeToRun = {
        print("operation2 started")

        self.talkWithServer(completion: { (completion) in
            print("operation2 completed")
        })
    }

    operationQueue?.addOperation(operation2)
}
设计:
  • 在您的实现中,
    MyOperation
    似乎是通用的,您似乎在调用它们的地方完成了大部分实际工作
  • 修改
    MyOperation
    以完成实际工作
  • 呼叫站点应该很简单
  • 示例
    FetchData()
    是一个操作,
    ParseData()
    是另一个操作
  • 因此,操作包含业务逻辑
  • 在调用站点,您可以添加依赖项

只需在依赖操作上添加依赖项即可

let queue = OperationQueue()

let operation1 = BlockOperation(block: { [weak self] in
    self?.doOperation1()
})

let operation2 = BlockOperation(block: { [weak self] in
    self?.doOperation2()
})

operation1.addDependency(operation2) // THIS IS THE KEY CODE IN YOUR CASE

queue.addOperation(operation1)
queue.addOperation(operation2)

希望这可以帮助您解决依赖性问题。

谢谢您的文档。我想使用OperationQueue而不是GCD。我正在试图弄清楚为什么依赖性不起作用我不确定我是否理解你的问题。您在问题的第2行中写道,操作1正在进行或完成后,可以开始操作2。这是一个输入错误,因为如果添加依赖项,它将等待操作1完成。为什么将
codeToRun添加到队列后要设置它。在将其添加到队列之前需要执行此操作。此操作的实现是从某处复制的吗?您的代码存在许多问题。请您阅读Operation.codeToRun的文档,然后再添加到队列中。更正。是否要在第一个操作完成后开始第二个操作?如果是这样,你能编辑你问题的第二行吗?更正,谢谢
let queue = OperationQueue()

let operation1 = BlockOperation(block: { [weak self] in
    self?.doOperation1()
})

let operation2 = BlockOperation(block: { [weak self] in
    self?.doOperation2()
})

operation1.addDependency(operation2) // THIS IS THE KEY CODE IN YOUR CASE

queue.addOperation(operation1)
queue.addOperation(operation2)