gpt4 book ai didi

ios - 为什么这个完成处理程序会跳过 for 循环

转载 作者:行者123 更新时间:2023-11-28 19:24:59 25 4
gpt4 key购买 nike

我有这组代码,我只想运行:self.performSegue 在所有 for 循环和所有 Firebase 的异步任务完成运行之后:

    getFeaturedPost(withCompletion: startNext)

func getFeaturedPost(withCompletion completion: () -> Void ) {
print("Getting featured posts...")
ref.child("featured").child("amount").observeSingleEvent(of: .value, with: { (snapshot) in
self.numberOfPosts = snapshot.value as! Int

print("There's \(self.numberOfPosts) posts avaliable.")

for pos in 0..<self.numberOfPosts{
print("Getting reference names for post: \(pos + 1)")
self.ref.child("featured").child("post\(pos + 1)").observeSingleEvent(of: .value, with: { (snapshot) in
let postID = (snapshot.value as? NSDictionary)?["postID"] as? String ?? ""
let userOfPost = (snapshot.value as? NSDictionary)?["userOfPost"] as? String ?? ""
self.customValues.append(("/users/public/\(userOfPost)/posts/\(postID)"))
})
}
})
print("Done! The posts are: \(customValues)")
completion()
}

func startNext()
{
getPostData(withCompletion: {
print("Finished getting data, going to main screen.")
self.performSegue(withIdentifier: "showHome", sender: nil)
})
}

func getPostData(withCompletion completion: () -> Void ) {
print("Getting idividual post data, there are \(customValues.count) posts")
for i in 0..<customValues.count {
print("Currently on post: \(i)")
let encodedURL = (customValues[i] + "/postURL")
ref.child(encodedURL).observe(.value, with: { (snapshot) in
if let newURL = snapshot.value as? String{
print("Sending \(newURL) to DemoSource Class")
DemoSource.shared.add(urlString: newURL)
}
})
}
completion()
}

但是 startNext() 函数(转到下一个 View )在 getFeaturedPost 开始之前执行它是 for 循环,它打印当前正在发布的帖子在。最后,当我使用 DemoSource.shared.add(urlString: newURL) 将数据发送到 demosource 类时,newURL 为 nil,我有一个控制台日志显示您各函数打印语句顺序:

Getting featured posts...
Done! The posts are: []
Getting idividual post data, there are 0 posts
Finished getting data, going to main screen. // This line should be printed last meaning this function is being executed too early
There's 2 posts avaliable.
Getting reference names for post: 1 // These two lines should be called before the line 'Finished getting data'
Getting reference names for post: 2

最佳答案

DispatchGroup 的使用非常简单。这是一种计数器。 enter 增加计数器,leave 减少它。如果计数器达到 0,则执行 notify 中的闭包。

  • 在异步 block 调用enter之前的循环中。
  • 在末尾调用 leave 的异步 block 内。
  • 循环后调用notify

    func getFeaturedPost(withCompletion completion: @escaping () -> Void ) {
    print("Getting featured posts...")
    ref.child("featured").child("amount").observeSingleEvent(of: .value, with: { (snapshot) in
    self.numberOfPosts = snapshot.value as! Int

    print("There's \(self.numberOfPosts) posts avaliable.")
    let group = DispatchGroup()
    for pos in 0..<self.numberOfPosts{
    group.enter()
    print("Getting reference names for post: \(pos + 1)")
    self.ref.child("featured").child("post\(pos + 1)").observeSingleEvent(of: .value, with: { (snapshot) in
    if let post = snapshot.value as? [String:Any] {
    let postID = post["postID"] as? String ?? ""
    let userOfPost = post["userOfPost"] as? String ?? ""
    self.customValues.append(("/users/public/\(userOfPost)/posts/\(postID)"))
    }
    group.leave()
    })
    }
    group.notify(queue: .main) {
    print("Done! The posts are: \(customValues)")
    completion()
    }
    })
    }

在其他方法中相应地实现一个组。

旁注:不要在 Swift 中使用 NS... 集合类型。

关于ios - 为什么这个完成处理程序会跳过 for 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59821135/

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