【问题标题】:Why NSOperation starts before completion previous operation?为什么 NSOperation 在完成之前的操作之前开始?
【发布时间】:2016-03-28 20:11:07
【问题描述】:

我正在尝试下一个:

  1. 我收到 Alamofire 的响应,填写一个数组
  2. 打印这个数组

为此我做了:

var queue = NSOperationQueue()

let firstOperation = NSBlockOperation(block: {
    let getMyProfileURL = "\(self.property.host)\(self.property.getMyProfile)"
     Alamofire.request(.POST, getMyProfileURL, parameters: self.userParameters.profileParameteres, encoding: .JSON).responseJSON { response in
         do {
              let json = JSON(data: response.data!)
              print(json)

              if json["user"].count > 0 {
                  self.profileDetails.append(ProfileDetailsModel(json: json["user"]))
              }
          }
      }
})

firstOperation.completionBlock = {
     print("firstOperation completed")
}

queue.addOperation(firstOperation)

let secondOperation = NSBlockOperation(block: {
     print(self.profileDetails)
})

secondOperation.addDependency(firstOperation.completionBlock)

secondOperation.completionBlock = {
    print(self.profileDetails)
}

queue.addOperation(secondOperation)

因此,理论上,首先它需要填充我的数组,完成此任务(块),然后再打印这些数组。但我明白了:

firstOperation completed
[] -> self.profileDetails from the secondOperation
[] -> self.profileDetails from the secondOperation completion block
and just here I get my JSON from the Alamofire 'do' block

那么,我做错了什么?以及如何解决它以使其按我的意愿工作?

【问题讨论】:

  • 您的块在请求发出后立即返回(因此操作完成),它不会等待异步调用返回。
  • 有什么解决办法吗?我想在开始打印之前获得完整的数组@dan

标签: ios swift concurrency nsoperation nsoperationqueue


【解决方案1】:

在第一个操作完成之前(例如,在第一个操作块的末尾),不要添加第二个操作。

【讨论】:

  • 所以我需要在 Alamofire 关闭之后添加这行 'queue.addOperation(secondOperation)'?
【解决方案2】:

首先,您必须了解Alamofire 请求始终在单独的线程中执行。

所以你的firstOperation 没用。你不需要它,因为 Alamofire 已经是异步的。

var queue = NSOperationQueue()

let secondOperation = NSBlockOperation(block: {
    print(self.profileDetails)
})


secondOperation.completionBlock = {
    print(self.profileDetails)
}

let getMyProfileURL = "\(self.property.host)\(self.property.getMyProfile)"
Alamofire.request(.POST, getMyProfileURL, parameters: self.userParameters.profileParameteres, encoding: .JSON).responseJSON { response in
    do {
        let json = JSON(data: response.data!)
        print(json)

        if json["user"].count > 0 {
            self.profileDetails.append(ProfileDetailsModel(json: json["user"]))
        }
    }

    print("Alamofire.request completed") // instead of: print("firstOperation completed")

    queue.addOperation(secondOperation)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多