gpt4 book ai didi

ios - 在 Swift 上安排一个接一个的任务但是使用 session

转载 作者:搜寻专家 更新时间:2023-11-01 07:27:07 25 4
gpt4 key购买 nike

试图了解我如何将一个任务安排在另一个任务之后,查看了 GCD 和 NSOperations,但两者似乎都处于与核心代码相去甚远的抽象状态;其中一部分在它自己的线程上执行!

我尝试了这段代码,这是我能找到的最明显的代码...

    let date = NSDate()
print("getting Links \(date)")

let operationQueue: NSOperationQueue = NSOperationQueue.mainQueue()
let completionBlockOperation: NSBlockOperation = NSBlockOperation.init(
block: {
self.reportFini()
}
)

let workerBlockOperation:NSBlockOperation = NSBlockOperation.init(
block: {
self.getLinks()
}
)
completionBlockOperation.addDependency(workerBlockOperation)
operationQueue.addOperation(workerBlockOperation)
operationQueue.addOperation(completionBlockOperation)

现在 reportFini 几乎什么都不做 ...

func reportFini() {
let date = NSDate()
print("got Links \(date)")
}

但 getLinks 更复杂,使用 session ......简而言之它运行

    let request = NSMutableURLRequest(URL: NSURL(string: "https://blah")!)
let session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"

request.addValue("application/json",forHTTPHeaderField: "Content-Type")
request.addValue("path", forHTTPHeaderField: lePath)
request.addValue("settings", forHTTPHeaderField: "requested_visibility\": \"public\"}")

var nodeA:NSMutableDictionary? = ["path":lePath]
let nodeB:NSMutableDictionary? = ["requested_visibility":"public"]
nodeA!.setValue(nodeB, forKey: "settings")

do {
let jsonData = try NSJSONSerialization.dataWithJSONObject(nodeA!, options: [])
request.HTTPBody = jsonData
} catch {
completion(string: nil, error: error)
}
var string2Return = ""
var stringPath = ""
let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
if let error = error {
completion(string: nil, error: error)
return
}
let strData = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Body: \(strData)\n\n")
do {
let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options:NSJSONReadingOptions.MutableContainers);
self.jsonParser(jsonResult,field2file: "ignore")

if let stringPath = (self.parsedJson["url"] as? String) {
string2Return = stringPath
} else {
string2Return = (self.parsedJson["error_summary"] as? String)!
}
completion(string: string2Return, error: error)
} catch {
completion(string: nil, error: error)
}
})
task.resume()

现在,getLinks 和 reportFini 同时执行@;基本上获取链接在它自己的线程上消失!并立即返回...但是我需要/希望在完成时得到通知,因为我还有其他事情要做。

它变得更加复杂,因为我需要同时运行 10 个 session (获取 10 个链接),所以是并行的;并希望在他们全部完成时得到通知。

---更新---

尝试将我的 session 代码包含在 GCD 中

    let workerQueue = dispatch_queue_create("getLinks", DISPATCH_QUEUE_CONCURRENT)
let getLinksGroup = dispatch_group_create()

dispatch_group_notify(getLinksGroup, dispatch_get_main_queue()) {
print("All Links Downloaded")
}

dispatch_group_enter(getLinksGroup)
dispatch_group_async(getLinksGroup, workerQueue) {

退出...

    dispatch_group_leave(getLinksGroup)

不幸的是,它不起作用;因为我已经看到 session 启动了它们自己的线程,而且我几乎立即收到代码已完成的通知,显然在它实际完成 URL 数据下载任务之前。

打算尝试使用 KVO ...

最佳答案

设法解决这个问题;使用 GCD & KVO,但不管理 session ;管理计数器,而不是通过更改受监视的 KVO 值来引发触发器。一个好的解决方案,你告诉我。

public class SynchronizedInt<T> {
private var blob:Int = 0
private let accessQueue = dispatch_queue_create("SynchronizedIntAccess", DISPATCH_QUEUE_SERIAL)

public func pending(queue2go:T) {
dispatch_sync(self.accessQueue) {
self.blob = queue2go as! Int
}
}

public func fulfilled() -> Bool {
dispatch_sync(self.accessQueue) {
self.blob = self.blob - 1
}
if self.blob == 0 {
return true
} else {
return false
}
}

public func copy() -> Int {
return self.blob
}

}

我用它来跟踪启动的 session ,这样我就可以在它们全部完成时收到通知。我在完成 block 中跟踪完成,每个 block 检查它是否是最后一个。除此之外,我还使用了基于此处介绍的第一个 Swifty 解决方案的 KVO。

http://blog.scottlogic.com/2015/02/11/swift-kvo-alternatives.html

关于ios - 在 Swift 上安排一个接一个的任务但是使用 session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35277402/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com