嵌套调度组Swift [英] Nested Dispatch Groups Swift

查看:190
本文介绍了嵌套调度组Swift的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当用户在我的应用程序中创建一个新组时,我必须将邀请推送到数据库以及其他信息。我已经开始使用调度组,以便跟踪所有信息何时成功发出,以便我可以关闭视图。



我试图使用邀请的调度组和所有数据的另一个调度组。下面是我所拥有的:

$ p $ //将新数据推送到db
func createGroup(onSccess completion:@escaping() - > Void){
let inviteDispatchGroup = DispatchGroup()
let dataDispatchGroup = DispatchGroup()

let uid = FIRAuth.auth()?。currentUser?.uid
let name = String(uid!)+_+ nameTextField.text!

//推送邀请
dataDispatchGroup.enter()
邀请邀请{
inviteDispatchGroup.enter()
let ref = FIRDatabase.database( ).reference()。child(users)。child(invite.id).child(invites)
ref.updateChildValues([name:nameTextField.text!]){(error,ref) - >无效
inviteDispatchGroup.leave()
}
}
inviteDispatchGroup.notify(队列:DispatchQueue.main,执行:{
dataDispatchGroup.leave()
)}

//存储图片
dataDispatchGroup.enter()
let storageRef = FIRStorage.storage()。reference()。child(profile_images)。child \(name).png)
如果let uploadData = UIImagePNGRepresentation(profImage.resizeImage(targetSize:CGSize(width:500,height:Int(500 *(profImage.size.height / profImage.size.width )))){
storageRef.put(uploadData,metadata:nil,completion:{(metadata,error)in
dataDispatchGroup.leave()
))
}
$ b $ // store pet info
dataDispatchGroup.enter()
let petRef = FIRDatabase.database()。reference()。child(pets)。child(name)
petRef.setValue([mod:uid !,name:nameTextField.text !,members:[uid!]]){(error,ref) - >无效
dataDispatchGroup.leave()
}
$ b $ //存储用户信息
dataDispatchGroup.enter()
let userRef = FIRDatabase.database() .reference()。child(users)。child(uid!)。child(pets)
userRef.updateChildValues([name:true]){(error,ref) - >无效
dataDispatchGroup.leave()
}

dataDispatchGroup.notify(队列:DispatchQueue.main,执行:{$ b $完成()
})





$ b

正如你所看到的,当 invitesDipatchGroup code>完成,相应的 dataDispatchGroup 剩下。



我是Dispatch组的新手,希望知道这是否是正确的处理方式。
<解决方案这是一个非常好的异步任务跟踪方法。

检查所有的代码是非常重要的路径覆盖了 leave()。如果如果let 不具有不可选的值,那么您有一个潜在的错误。在这里修正:

  func createGroup(onSccess completion:@escaping() - > Void){
[.. 。)
//存储图片
dataDispatchGroup.enter()
let storageRef = FIRStorage.storage()。reference()。child(profile_images)。child(\(name ).png)
如果let uploadData = UIImagePNGRepresentation(profImage.resizeImage(targetSize:CGSize(width:500,height:Int(500 *(profImage.size.height / profImage.size.width))))) {
storageRef.put(uploadData,metadata:nil,completion:{(metadata,error)in
dataDispatchGroup.leave()
})
} else {
dataDispatchGroup.leave()
}
[...]
}



一般来说,也要确保在所有使用的方法的代码路径中调用所有完成块。在Firebase中总会有一个错误,或者在这些方法的文档中可能会有一些关于完成的内容。但是,这又是一条路。


When a user creates a new group in my app I have to push invites to the database as well as other information. I've started using Dispatch Groups in order to keep track of when all the information is successfully sent out so I can dismiss the view.

I'm trying to use a dispatch group for the invites and another dispatch group for all the data. Here's what I have:

// Push new data to db
func createGroup(onSccess completion:@escaping () -> Void) {
    let inviteDispatchGroup = DispatchGroup()
    let dataDispatchGroup = DispatchGroup()

    let uid = FIRAuth.auth()?.currentUser?.uid
    let name = String(uid!) + "_" + nameTextField.text!

    // push invites
    dataDispatchGroup.enter()
    for invite in invites {
        inviteDispatchGroup.enter()
        let ref = FIRDatabase.database().reference().child("users").child(invite.id).child("invites")
        ref.updateChildValues([name: nameTextField.text!]) { (error, ref) -> Void in
            inviteDispatchGroup.leave()
        }
    }
    inviteDispatchGroup.notify(queue: DispatchQueue.main, execute: {
        dataDispatchGroup.leave()
    })

    // store picture
    dataDispatchGroup.enter()
    let storageRef = FIRStorage.storage().reference().child("profile_images").child("\(name).png")
    if let uploadData = UIImagePNGRepresentation(profImage.resizeImage(targetSize: CGSize(width: 500, height: Int(500*(profImage.size.height/profImage.size.width))))) {
        storageRef.put(uploadData, metadata: nil, completion: { (metadata, error) in
            dataDispatchGroup.leave()
        })
    }

    // store pet info
    dataDispatchGroup.enter()
    let petRef = FIRDatabase.database().reference().child("pets").child(name)
    petRef.setValue(["mod":uid!, "name":nameTextField.text!, "members":[uid!]]) { (error, ref) -> Void in
        dataDispatchGroup.leave()
    }

    // store user info
    dataDispatchGroup.enter()
    let userRef = FIRDatabase.database().reference().child("users").child(uid!).child("pets")
    userRef.updateChildValues([name: true]) { (error, ref) -> Void in
        dataDispatchGroup.leave()
    }

    dataDispatchGroup.notify(queue: DispatchQueue.main, execute: {
        completion()
    })
}

As you can see, when the invitesDipatchGroup is completed it's corresponding dataDispatchGroup is left.

I'm new to Dispatch groups and want to hear if this is the correct approach to be taking with this sort of task.

解决方案

This is a very good approach for async task tracking.

It is important to check if all code paths are covered with leave(). You have a potential bug, if the if let doesn't have the value not optional. Fixed here:

func createGroup(onSccess completion:@escaping () -> Void) {
    [...]
    // store picture
    dataDispatchGroup.enter()
    let storageRef = FIRStorage.storage().reference().child("profile_images").child("\(name).png")
    if let uploadData = UIImagePNGRepresentation(profImage.resizeImage(targetSize: CGSize(width: 500, height: Int(500*(profImage.size.height/profImage.size.width))))) {
        storageRef.put(uploadData, metadata: nil, completion: { (metadata, error) in
            dataDispatchGroup.leave()
        })
    } else {
        dataDispatchGroup.leave()
    }
    [...]
}

In general always also make sure that all completion blocks are called in all of the code paths of methods you use. There always may be a bug in Firebase or there may be something about the completion not being called in the documentation of those methods. But again, this is the way to go.

这篇关于嵌套调度组Swift的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆