Изображение с низким разрешением занимает слишком много времени для загрузки
Используя Facebook Graph API, я получил строковый URL-адрес 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()
}
2 ответа
Вы должны переместить все 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
, Это позволяет контроллеру представления освободить, если пользователь отклоняет его, и процедуры завершения тогда возвращаются рано, не делая никакой ненужной работы.
Этот код является незаконным:
NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: self.profilePictureUrl)!, completionHandler: { (data, response, error) ->
Void in
self.profilePictureImageView.image = UIImage(data: data!)
Стоп! Вы устанавливаете изображение UIImageView в фоновом потоке. Нет нет нет. UIKit не является потокобезопасным. Вы должны попасть в основной поток, чтобы сделать это. (В конечном итоге вы попадаете в основной поток в своем коде, но делаете это слишком поздно.)