[英]Swift iOS -DispatchGroup with URLSession is locking other parts of app that it is not located in
I have an array of up to 6 images. 我有最多6张图片的阵列。 I use a loop to loop through all of the images, turn them into metadata, send the metadata to Storage and then when done I send the url strings to Firebase Database.
我使用循环遍历所有图像,将它们转换为元数据,将元数据发送到存储,然后在完成后将url字符串发送到Firebase数据库。
I'm using DispatchGroup to control the loop as the Url is changed to Data so I can send the data to Firebase Storage. 当Url更改为Data时,我正在使用DispatchGroup来控制循环,因此可以将数据发送到Firebase Storage。
If this loop is happening in tabOne, if i go back and forth to tabTwo or tabThree, when the loop finishes and the alert appears, tabTwo is temporarily locked or tabThree gets temporarily locked for around 2-3 seconds. 如果在tabOne中发生此循环,如果我来回切换至tabTwo或tabThree,则在循环结束并显示警报时,tabTwo被临时锁定,或者tabThree被临时锁定约2-3秒。 I cannot figure out where I'm going wrong?
我无法弄清楚哪里出了问题?
I'm not sure if it makes a difference but I'm using a custom alert instead of the UIAlertController. 我不确定是否会有所不同,但我使用的是自定义提醒,而不是UIAlertController。 It's just some UIViews and a button, it's nothing special so I didn't include the code.
它只是一些UIViews和一个按钮,没什么特别的,所以我没有包含代码。
var urls = [URL]()
picUUID = UUID().uuidString
dict = [String:Any]()
let myGroup = DispatchGroup()
var count = 0
for url in urls{
myGroup.enter() // enter group here
URLSession.shared.dataTask(with: url!, completionHandler: {
(data, response, error) in
guard let data = data, let _ = error else { return }
DispatchQueue.main.async{
self.sendDataToStorage("\(self.picUUID)_\(self.count).jpg", picData: data)
self.count += 1
}
}).resume()
// send dictionary data to firebase when loop is done
myGroup.notify(queue: .main) {
self.sendDataToFirebaseDatabase()
self.count = 0
}
}
func sendDataToStorage(_ picId: String, picData: Data?){
dict.updateValue(picId, forKey:"picId_\(count)")
let picRef = storageRoot.child("pics")
picRef.putData(picData!, metadata: nil, completion: { (metadata, error) in
if let picUrl = metadata?.downloadURL()?.absoluteString{
self.dict.updateValue(picUrl, forKey:"picUrl_\(count)")
self.myGroup.leave() // leave group here
}else{
self.myGroup.leave() // leave group if picUrl is nil
}
}
}
func sendDataToFirebaseDatabase(){
let ref = dbRoot.child("myRef")
ref.updateChildValues(dict, withCompletionBlock: { (error, ref) in
displaySuccessAlert()
}
}
I don't know much about Firebase, but you are dispatching your sendDataToFirebaseDatabase
method to main queue which probably explains why your UI becomes unresponsive. 我对Firebase不太了解,但是您正在将
sendDataToFirebaseDatabase
方法调度到主队列,这可能解释了UI变得无响应的原因。
Dispatch sendDataToFirebaseDatabase
to a background queue and only dispatch your displaySuccessAlert
back to main queue. 将
sendDataToFirebaseDatabase
到后台队列,仅将displaySuccessAlert
分配回主队列。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.