1
다른 비트의 코드를 실행하기 전에 업로드를 완료하고 응답을 얻으려는 요청을 보내는 작업을 기다리는 방법을 알고 싶습니다. 나는 NSOperations이 작업을 수행하려고 시도했습니다다음 작업을 실행하기 전에 요청이 완료되기를 기다리는 중
이let testOp = BlockOperation {
var result = 0
for i in 1...1000000000 {
result += i
}
}
let logOp = BlockOperation {
self.debug.log(tag: "test", content: "testing")
}
logOp.completionBlock = {
print("------- logOp completed")
}
logOp.addDependency(testOp)
let sendOp = BlockOperation {
self.debug.sendLog() //uploads log, using URLSession.shared.dataTask
}
sendOp.completionBlock = {
print("------- sendOp completed")
}
sendOp.addDependency(logOp)
let emptyOp = BlockOperation {
self.debug.empty()
}
emptyOp.completionBlock = {
print("------- emptyOp completed")
}
emptyOp.addDependency(sendOp)
let queue = OperationQueue()
queue.addOperations([testOp, logOp, sendOp, emptyOp], waitUntilFinished: false)
출력 : 나는 수 출력을 예상 내 코드를 기반으로
------- logOp completed
*** Sending debug log (coming from self.debug.sendLog())
------- sendOp completed
------- emptyOp completed
*** sendLog uploaded (coming from self.debug.sendLog())
:
------- logOp completed
*** Sending debug log
*** sendLog uploaded
------- sendOp completed
------- emptyOp completed
가 어떻게 그렇게해야합니까 ? NSOperations에서이 작업을 수행 할 수 있습니까? debug.sendLog() 함수에 대한
추가 세부 사항 :
func sendLog() {
...
var urlRequest = URLRequest(url: url!)
urlRequest.httpMethod = "POST"
...
let session = URLSession.shared
let task = session.dataTask(with: urlRequest, completionHandler: {
(data, response, error) in
...
DispatchQueue.main.async {
print("*** sendLog uploaded")
}
})
task.resume()
}
"내 코드를 기반으로 내가 될 수있는 출력을 예상 ...". 분명히 말하면, 그 기대는 잘못되었습니다. 'print ("*** sendLog uploaded")'는 * 메인 큐 *에서 비동기 적으로 실행되는 반면 NSOperationQueue는 디폴트로 글로벌 동시 디폴트 (우선 순위) 디스패치 큐 *로 실행됩니다. – makadev
'DispatchQueue.main.async' 블록을 완전히 제거하도록 코드를 조정했습니다. 이것은 결과를 바꾸는 것처럼 보이지 않습니다. 세마포어를 사용하여 요청을 대기 상태로 만들 수 있었지만이 경우에는 해킹이 느껴집니다. 나는 어떻게 NSoperations가 유용한지 보지 않는다. 물론 상태를 확인할 수 있고 모든 작업을 쉽게 취소 할 수 있습니다. 코드를 잘 구조화했다면 취소해야 할 트랙까지 멀리 떨어져서는 안됩니다. – toast
사실, 또 다른 문제점은 dataTask가 이미'task.resume()'과 비동기 적으로 실행된다는 것입니다. 언급 한대로 비동기 "콜백"/ "미래"/ "약속"또는 단순성 - [동기 요청] (http://stackoverflow.com/a/34308158/3828957)을 처리 할 수있는 또 다른 개념이 필요할 수 있습니다. * 또는 다른 메커니즘 *. 세마포어 변종은 hackish로 보일 수도 있고 느낄 수도 있지만, 짧고 유지 보수가 쉬운 해결책이며, 과도하게 사용하지 않고 주 큐를 막지 않도록주의해야합니다. – makadev