Ios 调度组在工作完成前通知
我是苹果GCD的新手,对调度组有问题。 因此,我试图在post完全初始化后将post附加到地图。在Ios 调度组在工作完成前通知,ios,swift,multithreading,Ios,Swift,Multithreading,我是苹果GCD的新手,对调度组有问题。 因此,我试图在post完全初始化后将post附加到地图。在post.init内部,有一个URLSession从url下载UIImage。但即使在下载完成之前,group.notify也会被触发。我真的找不出原因是什么。下面是代码。我真的很感激任何建议或帮助!谢谢 // ViewController.swift let group = DispatchGroup ... ... group.enter() DispatchQueue.global(qos:
post.init
内部,有一个URLSession
从url下载UIImage
。但即使在下载完成之前,group.notify
也会被触发。我真的找不出原因是什么。下面是代码。我真的很感激任何建议或帮助!谢谢
// ViewController.swift
let group = DispatchGroup
...
...
group.enter()
DispatchQueue.global(qos: .userInitiated).async {
post = Post(values: post)
self.posts[postId] = post
group.leave()
}
group.notify(queue: DispatchQueue.main, execute: {
print("notify:: \(post?.picture)") // This prints out nil, when it shouldn't.
self.addPostToMap(post!, at: location!)
})
// Post.swift
class Post {
var picture: UIImage?
var thumbnail: UIImage?
init(values: [String: Any]) {
...
URLSession.shared.dataTask(with: url!, completionHandler: {(data, response, error) in
DispatchQueue.main.async {
self.picture = UIImage(data: data!)
self.thumbnail = Util.resizeImage(image: self.picture!, targetSize: CGSize(width: 50, height: 50))
}
}).resume()
}
}
init中的完成处理程序(值:)仅在任务完成时触发,无论何时。但是,在调用.resume()之后,代码将继续执行,这意味着init将退出,并且您的group.notify块将立即被调用 你可以用不同的方法处理这个问题。一种方法是为Post类设置委托协议,并将ViewController设置为该委托。在完成处理程序中,您可以调用一个函数(为了参数起见,将其调用为didfish()),该函数将告诉视图控制器任务已完成。您可以将通知包装到该函数中 但是,如果这样做,我会将dataTask从init函数中去掉。原因是委托通常声明为隐式展开的选项,并从创建类中设置。因此,初始化类时,在调用委托回调时,委托可能不会引用任何内容 因此,结构如下:
// ViewController.swift
class ViewController : UIViewController, PostDelegate {
let group = DispatchGroup
...
...
group.enter()
DispatchQueue.global(qos: .userInitiated).async {
post = Post(values: post)
post.delegate = self
post.getImage() // New function
self.posts[postId] = post
group.leave()
}
....
func didFinish() -> Void {
group.notify(queue: DispatchQueue.main, execute: {
print("notify:: \(post?.picture)")
self.addPostToMap(post!, at: location!)
})
....
Protocol PostDelegate {
func didFinish() -> Void
}
// Post.swift
class Post {
var delegate : PostDelegate!
var picture: UIImage?
var thumbnail: UIImage?
init(values: [String: Any]) {
...
}
func getImage() -> Void {
URLSession.shared.dataTask(with: url!, completionHandler: {(data, response, error) in
DispatchQueue.main.async {
self.picture = UIImage(data: data!)
self.thumbnail = Util.resizeImage(image: self.picture!, targetSize: CGSize(width: 50, height: 50))
if delegate != nil {
delegate.didFinish() // Tell the delegate you are done
}
}
}).resume()
}
}
希望这是有意义的,更重要的是,它有帮助 谢谢您的回复,但是取出notify会有问题,因为我现在无法从
didfish
访问变量post
和location
。有什么建议吗?事实上是我做的!我通过委托方法传递了变量。谢谢