[英]DispatchGroup notify() called immediately - not waiting for Enter/Leave
I've been stuck with this problem for some time now, and I ran out of useful google results.我已经被这个问题困扰了一段时间,我用完了有用的谷歌结果。
I've got two requests, the first one retrieves some links from a server and in the other request I download the images from the links.我有两个请求,第一个请求从服务器检索一些链接,在另一个请求中我从链接下载图像。 After all the images finished downloading, I return the result to a view controller.在所有图像下载完成后,我将结果返回给视图控制器。
Int the code requestBanners()
is called from a UIViewController, entering the dispatch group.从 UIViewController 调用代码requestBanners()
,进入调度组。 In theory, before leaving the dispatch group storeImage()
should be called for every url that I got from the server, and on every call it should enter and leave the dispatch group, adding the image to an array.理论上,在离开调度组之前,应该为我从服务器获得的每个 url 调用storeImage()
,并且在每次调用时它都应该进入和离开调度组,将图像添加到数组中。 Once finished downloading all the images, it leaves the dispatch group, and fires the notify()
to execute setUpCollection()
on the UIViewController.完成下载所有图像后,它离开调度组,并触发notify()
以在 UIViewController 上执行setUpCollection()
。
Using print()
as guidance to see what's really happening, I get:使用print()
作为指导来查看真正发生的事情,我得到:
I'm downloading the urls我正在下载网址
Now I'm in the UIViewController (this
print()
is called in the implementation ofsetUpCollection()
)现在我在 UIViewController (这个print()
在setUpCollection()
的实现中被调用)
I'm downloading an image我正在下载图片
When it actually should be downloading the urls, then downloading the images and only then, returning to the UIViewController当它实际上应该下载 url 时,然后下载图像,然后才返回 UIViewController
I've used semaphores at first, but then I thought using a dispatch group would be a cleaner solution.我一开始使用了信号量,但后来我认为使用调度组会是一个更干净的解决方案。
On both approaches, the empty bannersArr is returned before finishing downloading the images.在这两种方法中,在完成下载图像之前返回空的 bannersArr。 Maybe that compact map is messing everything up.也许那张紧凑的地图把一切都搞砸了。
Here's the code:这是代码:
class BannersHelper {
private var bannersArr: [UIImage] = []
private let dispatchGroup = DispatchGroup()
private var delegate: LoadBanners? = nil
init(delegate: LoadBanners) {
self.delegate = delegate
dispatchGroup.notify(queue: .main) {
self.delegate?.setUpCollection(errImg: self.bannersArr)
}
}
func requestBanners() {
print("I'm downloading the urls\n")
self.dispatchGroup.enter()
ServiceParametria.getBanners(handler: { response in
guard let bannersResponse = response as? BannerModel else {
return
}
let banners = bannersResponse.data as! [DataBannerModel]
let _ = banners.compactMap({self.storeImage(model: $0)})
self.dispatchGroup.leave()
})
}
private func storeImage(model: DataBannerModel) {
print("I'm downloading an image\n")
self.dispatchGroup.enter()
ServiceParametria.getImage(url: model.urlImagen!, handler: { result in
let image = result as! UIImage
self.bannersArr.append(image)
self.dispatchGroup.leave()
})
}
}
Is there a better way to do this or am I just using the dispatch group wrong?有没有更好的方法来做到这一点,还是我只是错误地使用了调度组?
As @pkamb pointed out in the comments the problem was that I was trying to fire the dispatchGroup.notify()
inside the init()
method.正如@pkamb 在评论中指出的,问题是我试图在init()
方法中触发dispatchGroup.notify()
。
At that time of the execution, as I didn't call requestBanners()
yet, the DispatchGroup counter was equal to zero and that led to a an early call to the delegate?.setUpCollection()
with an empty array.在执行的那个时候,由于我还没有调用requestBanners()
,DispatchGroup 计数器等于 0,这导致提前调用了带有空数组的delegate?.setUpCollection()
。
Moving the dispatchGroup.notify()
block at the end of the requestBanners()
method solved the problem :)移动requestBanners()
方法末尾的dispatchGroup.notify()
块解决了问题:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.