Ios 安排一个接一个的任务,但在Swift上有会话

Ios 安排一个接一个的任务,但在Swift上有会话,ios,swift,session,grand-central-dispatch,nsoperation,Ios,Swift,Session,Grand Central Dispatch,Nsoperation,试图理解我如何安排一个任务后面的另一个任务,查看了GCD和NSO操作,但两者似乎都是抽象的,与核心代码相去甚远;其中一部分在自己的线程上执行 我尝试了这个代码,这是我能找到的最明显的 let date = NSDate() print("getting Links \(date)") let operationQueue: NSOperationQueue = NSOperationQueue.mainQueue() let completionBlockOpe

试图理解我如何安排一个任务后面的另一个任务,查看了GCD和NSO操作,但两者似乎都是抽象的,与核心代码相去甚远;其中一部分在自己的线程上执行

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

    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)")
}
但是GetLink更复杂,使用会话。。。简言之,它在运行

    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个会话(获取10个链接),所以是并行的;并希望在他们全部完成时得到通知

---更新---

尝试将我的会话代码包含在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)
不幸的是,它不起作用;因为我已经看到会话启动了自己的线程,我几乎立即得到通知,代码已经完成,显然在它实际完成URL数据下载任务之前


尝试使用KVO…

设法解决了这个问题;使用GCD和KVO,但不管理会话;管理计数器,然后通过更改监视的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
}

}
公共类同步{
私有变量blob:Int=0
private let accessQueue=dispatch\u queue\u create(“synchronizedEntaccess”,dispatch\u queue\u SERIAL)
公共函数挂起(队列2GO:T){
调度同步(self.accessQueue){
self.blob=queue2go as!Int
}
}
公共函数已实现()->Bool{
调度同步(self.accessQueue){
self.blob=self.blob-1
}
如果self.blob==0{
返回真值
}否则{
返回错误
}
}
public func copy()->Int{
返回self.blob
}
}
我正在使用它跟踪启动的会话,以便在它们全部完成时通知我。我在完成块中跟踪完成,每个块都检查它是否是最后一个。除此之外,我还使用了基于这里介绍的第一个快速解决方案的KVO


也许这可以帮助你,我不知道你会怎么看待GCD的抽象。这是一个尽可能低的API级别。我想你们需要的是调度组;我刚刚看了一段关于使用GCD小组的视频,但我仍然不太了解这个想法。当my session.dataTaskWithRequest启动时,它似乎启动了自己的线程并几乎立即返回,即使它尚未完成任务;完成块在拥有所有数据之前触发。如果我将其包装在GCD对象中;即使会话仍在忙着下载数据,这种情况也不会立即出现吗;一个比较老的帖子,但看起来很有希望,这是否符合要求。需要专家的意见。