gpt4 book ai didi

ios - 在异步调用完成后如何运行代码并且代码在 swift 3 中的异步函数之外

转载 作者:行者123 更新时间:2023-11-28 10:56:15 24 4
gpt4 key购买 nike

我有一个包含帖子 ID 的数组,然后我执行 for 循环并检索每个帖子内容并将帖子附加到帖子数组。循环结束后,我需要在完成处理程序中返回 post 数组。

但是,.observeSingleEvent 是一个异步方法,因此帖子内容是从 Firebase 检索的,completionhandler(posts) 已经执行,返回一个空数组。我想在每个帖子附加到数组后返回数组,类似于使这些方法同步。

static func getPost(postKeys:[String], completionHandler: @escaping ([Post])->()){
var posts = [Post]()
for postKey in postKeys{
let postRef = DataService.ds.REF_POSTS.child(postKey)
postRef.observeSingleEvent(of: .value, with: { (snapshot) in
if let postDict = snapshot.value as? Dictionary<String, Any>{
//create a post and append it to the post array
let key = snapshot.key
let post = Post(postKey: key, postData: postDict)
posts.append(post)
}
})
}
completionHandler(posts)
}

最佳答案

您可以使用 DispatchGroup在一系列任务完成后执行一些代码。

在开始任务之前调用enter 函数,在任务完成后调用leave 函数。您可以使用 notify 提供一个闭包,一旦所有任务都“离开”DispatchGroup 就会执行该闭包。

您还需要注意避免更新数组的并发问题; Swift 数组不是线程安全的。在串行调度队列上执行数组更新可以解决此问题。

static func getPost(postKeys:[String], completionHandler: @escaping ([Post])->()){
var posts = [Post]()
let dispatchGroup = DispatchGroup()
let arrayQueue = DispatchQueue(label: "arrayQueue")
for postKey in postKeys{
dispatchGroup.enter()
let postRef = DataService.ds.REF_POSTS.child(postKey)
postRef.observeSingleEvent(of: .value, with: { (snapshot) in
if let postDict = snapshot.value as? Dictionary<String, Any>{
//create a post and append it to the post array
let key = snapshot.key
let post = Post(postKey: key, postData: postDict)
arrayQueue.sync {
posts.append(post)
}
}
dispatchGroup.leave()
})
}

dispatchGroup.notify(queue: DispatchQueue.main) {
completionHandler(posts)
}
}

关于ios - 在异步调用完成后如何运行代码并且代码在 swift 3 中的异步函数之外,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43334899/

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