2016-08-12 8 views
0

Facebook Graph APIを使用して、に表示する200x200のプロフィール画像の文字列URLを取得しました。私は正常にこれを行うことができますが、画像が画面に表示されるまでに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

非同期呼び出しの外でサブビューを追加して、サブブロックの画像を補完ブロックに設定してみてください。 – brandonscript

答えて

3

あなたは、ほとんどの部分のUIKitとしてメインスレッド上にすべてUIViewコール(あなたがUIImageViewに設定されたので、何かを)移動する必要があり、スレッドセーフではありません。あなたは、パフォーマンスの最適化のためにかかわらず、バックグラウンドスレッドでUIImageをインスタンス化するので、この試すことができます:私はweakselfにあなたの参照を-ifiedたことも

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() 
} 

注意を。完了ルーチンが呼び出されるまでにこのコードを開始しているビューコントローラをユーザーが解消していないことを保証するものではないため、selfを強く参照しないようにしてください。これにより、ユーザーが不要にした場合にView Controllerが割り当てを解除し、完了ルーチンが不要な作業をせずに早期に戻ることができます。

+0

これらの改善のためにありがとうございます。私は興味があります - 意図的に 'strongSelf'への2つの参照を作成しましたか?私はXcodeがこれらの宣言の1つに対して警告を出すので尋ねるだけです。 – AlexanderHart

+0

はい、それぞれのコールバックが潜在的にスレッドをホッピングするので、 'strongSelf'への参照が2つ必要です。 Xcodeが変数名の1つを変更しなければならないと訴えているので、例えば内側の変数を 'strongSelfInner'にしてください。 – par

0

このコードは違法です:

NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: self.profilePictureUrl)!, completionHandler: { (data, response, error) -> 
    Void in 
    self.profilePictureImageView.image = UIImage(data: data!) 

ストップ! UIImageViewの画像を背景スレッドに設定しています。ダメダメダメ。 UIKitはスレッドセーフではありません。これを行うには、メインスレッドに乗る必要があります。 (あなたは最終的にあなたのコードのメインスレッドに行きますが、遅すぎます)

関連する問題