Using Facebook Graph API, I retrieved a string URL to a 200x200
profile picture that I want to display in a UIImageView
. I’m successfully able to do this, but I notice that it can take as long as 10 seconds for the image to display on the screen. Can anyone give me some pointers (no pun intended) on how to optimize it?
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()
}
2
Answers
You should move all
UIView
calls (so anything you set on theUIImageView
) onto the main thread as UIKit for the most part isn’t thread-safe. You can instantiate theUIImage
on the background thread though for performance optimization, so try this:Note also that I’ve
weak
-ified your references toself
. There is no guarantee the user hasn’t dismissed the view controller that is initiating this code by the time the completion routines get called so you want to make sure you’re not keeping a strong reference toself
. This allows the view controller to deallocate if the user dismisses it and the completion routines then return early without doing any unnecessary work.This code is illegal:
Stop! you are setting a UIImageView’s image on a background thread. No no no. UIKit is not thread-safe. You must get onto the main thread to do this. (You do eventually get onto the main thread in your code, but you are doing it too late.)