使用Facebook Graph API,我检索了一个200x200
个人资料图片的字符串网址,我想在UIImageView
中显示。我已经成功地做到了这一点,但我注意到图像在屏幕上显示可能需要长达10秒的时间。关于如何优化它,任何人都可以给我一些指示(没有双关语)吗?
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: self.profilePictureUrl)!, completionHandler: { (data, response, error) ->
Void in
self.profilePictureImageView.image = UIImage(data: data!)
self.profilePictureImageView.layer.cornerRadius = self.profilePictureImageView.frame.size.width / 2;
self.profilePictureImageView.clipsToBounds = true
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.view.addSubview(self.profilePictureImageView)
})
}).resume()
}
答案 0 :(得分:3)
您应该将所有UIView
次调用(以及您在UIImageView
上设置的任何内容)移动到主线程上,因为UIKit大部分都不是线程安全的。您可以在后台线程上实例化UIImage
以进行性能优化,请尝试以下操作:
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
let url = NSURL(string: self.profilePictureUrl)!
NSURLSession.sharedSession().dataTaskWithURL(
url,
completionHandler: { [weak self] (data, response, error) -> Void in
guard let strongSelf = self else { return }
// create the UIImage on the background thread
let image = UIImage(data: data!)
// then jump to the main thread to modify your UIImageView
dispatch_async(dispatch_get_main_queue(), { [weak self] () -> Void in
guard let strongSelf = self else { return }
let profilePictureImageView = strongSelf.profilePictureImageView
profilePictureImageView.image = image
profilePictureImageView.layer.cornerRadius = profilePictureImageView.frame.size.width / 2;
profilePictureImageView.clipsToBounds = true
strongSelf.view.addSubview(profilePictureImageView)
})
}
).resume()
}
另请注意,我weak
- 您对self
的引用。在完成例程调用之前,无法保证用户没有解除启动此代码的视图控制器,因此您需要确保没有保留对self
的强引用。这允许视图控制器在用户解除它时解除分配,然后完成例程然后提前返回而不做任何不必要的工作。
答案 1 :(得分:0)
此代码非法:
NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: self.profilePictureUrl)!, completionHandler: { (data, response, error) ->
Void in
self.profilePictureImageView.image = UIImage(data: data!)
停止!您正在后台线程上设置UIImageView的图像。不不不。 UIKit不是线程安全的。你必须进入主线程才能做到这一点。 (你最终会进入代码中的主线程,但是你做得太晚了。)