Swift 3 - DispatchQueue 内部函数

标签 swift dispatch-queue

我在 DispatchQueue.main.async 中调用了一个函数。这是我的代码:

let group = DispatchGroup()
group.enter()

DispatchQueue.main.async {
        for i in 0 ... (Global.selectedIcons.count - 1) {
            if self.albumorphoto == 1 {
                if i == 0 {
                    self.detector = 1
                    self.uploadPhoto() //here
                }
                else {
                    self.detector = 2
                    self.uploadPhoto() //here
                }
            }
            else {
                self.uploadPhoto() //here
            }
        }
        group.leave()
    }

    group.notify(queue: .main) {
        print("done")
    }
}

func uploadPhoto(){
    var request = URLRequest(url: URL(string: url)!)
    request.httpMethod = "POST"
    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")

    let params = param

    request.httpBody = params.data(using: String.Encoding.utf8)

    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        guard let data = data, error == nil else {
            print("error=\(error!)")
            return
        }

        if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
            print("statusCode should be 200, but is \(httpStatus.statusCode)")
            print("response = \(response!)")
        }

        let responseString = String(data: data, encoding: .utf8)
        print("responseString = \(responseString!)")

        if self.detector == 1 {
            self.album = self.parseJsonData(data: data)
        }

    }

    task.resume()
}

func parseJsonData(data: Data) -> [AnyObject] {
    do {
        let jsonResult = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as? NSDictionary
        let jsonalbum = jsonResult!["data"] as? [AnyObject]
        for jsonAlbum in jsonalbum! {
            self.folderID = jsonAlbum["id"] as! String
        }
    } catch {
        print(error)
    }

    return album
}

我想让它等到 DispathcQueue 中的所有任务完成。它可以工作,但问题是我的函数 uploadPhoto()。它不能等到 uploadPhoto() 完成它的任务。有解决这个问题的想法吗?谢谢!

最佳答案

在这里使用 DispatchGroup 是正确的选择,但是您必须为每个异步任务进入离开:

let group = DispatchGroup()
photos.forEach { photo in

    group.enter()
    // create the request for the photo

    URLSession.shared.dataTask(with: request) { data, response, error in

        group.leave()
        // handle the response

    }.resume()
}
group.notify(queue: .main) {
    print("All photos uploaded.")
}

您不需要 DispatchQueue.async() 调用,因为 URLSession.shared.dataTask 已经是异步的。

在我的代码中,我假设您想将对象建模为 Photo 并将 Global.selectedIcons.count 替换为 photos 数组:

class Photo {
    let isAlbum: Bool
    let isDefector: Bool
    let imageData: Data
}

我建议您看看 AlamofireSwiftyJSON进一步改进您的代码。这些是流行的库,可以更轻松地处理网络请求。使用它们,您几乎可以将整个 uploadPhoto()/parseJsonData() 函数简化为如下所示:

Alamofire.upload(photo.imageData, to: url).responseSwiftyJSON { json in
    json["data"].array?.compactMap{ $0["id"].string }.forEach {
        self.folderID = $0
    }
}

这使您的代码更加稳定,因为它消除了所有强制解包。 Alamofire 还为您提供上传进度和恢复和取消请求等功能。

关于Swift 3 - DispatchQueue 内部函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49726196/

相关文章:

swift - 有没有一种特定的方法可以将 DispatchWorkItems 附加到 DispatchQueue 而不是在代码中重新声明它们?

swift - NSMutableAttributedString 无法正确呈现

swift - Swift 中函数类型作为参数类型的优点?

ios - collectionViewCell 内的嵌入式 collectionView 未固定到安全区域布局

objective-c - Swift 字符串格式与 Objective-C

ios - 如何在 Swift UI 列表中的项目中制作可调整大小的文本

Swift取消DispatchQueue进程

ios - 如何监控递归调度队列的任务何时全部完成?

ios - UIScrollView 将元素定位在屏幕底部,而不是 ScrollView 底部

ios - 从后台线程播放 AVAudioPlayer 实例有时会失败