2017-12-27 27 views
0

を使用してUIImageViewを更新している間は、どのCollectionViewCell上のユーザーのクリックは、新しいビューがをスクロールとをズームするために表示されるとき、です。基本的に私はMyCollectionViewControllerとMyScrollViewControllerという2つの異なるクラスを持っています。クラッシュ:私は実装したい何SDWebImage

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath){ 
    let storyboard = UIStoryboard(name: "Main", bundle: nil) 
    let VC = storyboard.instantiateViewController(withIdentifier: "myScrollVC") as? MyScrollViewController 
    self.navigationController?.pushViewController(VC!, animated: true) 
    VC?.setImageToScrollView(image_URL: (self.jsonData?.HD_WALLPAPER![indexPath.row].wallpaper_image)!) 
} 

そして私は私のスクロールビューコントローラのコード部分を、次のしている:私は私のコレクションビューコントローラのコード部分を、次のしている私はSDWebImage ...オープンソースのライブラリを使用しています

import UIKit 
import SDWebImage 
class MyScrollViewController: UIViewController, UIScrollViewDelegate { 
    @IBOutlet weak var myImageView: UIImageView! 
    @IBOutlet weak var myScrollView: UIScrollView! 
    override func viewDidLoad(){ 
     super.viewDidLoad() 
     self.myScrollView.minimumZoomScale = 1.0 
     self.myScrollView.maximumZoomScale = 6.0 
    } 
    public func setImageToScrollView(image_URL: String){ 
     DispatchQueue.main.async { 
      self.myImageView!.sd_setImage(with: URL(string: image_URL), completed: { 
       (image, error, cacheType, url) in 
       //Completion Block ... Do Nothing 
      }) 
     } 
    } 
    override func didReceiveMemoryWarning(){ 
     super.didReceiveMemoryWarning() 
    } 
    func viewForZooming(in scrollView: UIScrollView) -> UIView?{ 
     return self.myImageView 
    } 
} 

画像キャッシュを管理する。

問題:エラーを以下にSDWebImage枠組みのsd_setImage APIを実行しながら、時々画像がエラーなしで正常にロードされますが、ほとんどの時間は、私のアプリがクラッシュ ...... enter image description here

致命的なエラー:オプションの値

をアンラップしながら、予期せずnilを見つけ

QUERY

  1. は、まず私がpushViewControllerと呼ばれ、その後、私は私のカスタム定義関数と呼ばれます。コレクションビューのセルから関数を呼び出す方法は適切ですか?
  2. オプションの値をアンラップしている間に予期せずnilが見つかったのはなぜですか?エラーフリーの画像URLが表示されます。
+0

それは 'self.myImageView'が' nil'だと思われます –

+0

@RajibTheKing強制的にアンラップするのではなくimageViewのバインディングをしてください。あなたのimageViewはいつもあなたのアプリがクラッシュするためにいつも無事になっています –

答えて

0

あなたの質問に戻って:

Firstly I called pushViewController and then I called my custom defined function. Is it proper way to call functions from collection view cell?

答えをこれには、あなたがのviewDidLoadまでコンセントを参照する関数を呼び出すべきではないということです。コンセントは暗黙的にラップされていないオプションですが、viewDidLoadまでそこに存在することは保証されていません。だから、あなたは競争状態にある。時にはそれが動作します。あなたはURLを渡すが、関数を呼び出さないように

変更を:imgURLがMyScrollViewContainer上のインスタンス変数がある

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath){ 
    let storyboard = UIStoryboard(name: "Main", bundle: nil) 
    let VC = storyboard.instantiateViewController(withIdentifier: "myScrollVC") as? MyScrollViewController 
    self.navigationController?.pushViewController(VC!, animated: true) 
    VC.imgURL = self.jsonData?.HD_WALLPAPER![indexPath.row].wallpaper_image)! 
} 

。次に、imgURLを渡してviewDidLoadから関数を呼び出します。

override func viewDidLoad(){ 
    super.viewDidLoad() 
    self.myScrollView.minimumZoomScale = 1.0 
    self.myScrollView.maximumZoomScale = 6.0 
    setImageToScrollView(image_URL: imgURL) 
} 

これにより、コールのタイミングが変わります。これにより、関数が呼び出されたときにコンセントが実際に存在することが保証されます。

===残りは(まだ関連が、あなたの問題を解決しませんでした)私の以前の答えです===

あなたはDispatch.asyncにSetImage呼び出しをラップする必要はありません。あなたの関数は1行でなければなりません:

public func setImageToScrollView(image_URL: String){ 
    self.myImageView.sd_setImage(with: URL(string: image_URL)) 
} 

これで問題は解決します。SetImageは独自のディスパッチを行い、コンセントがまだ存在する場合にのみUIを更新します。

他のコメント者は、あなたのコードがクラッシュすることがある(self.myImageViewは非同期ブロックが終了したときにはnilになる)と、UIImageViewコンセントがまだ存在するかどうかを確認するバインディングやガードに対して保護する方法を指摘しました。これらは一般的に関連するテクニックですが、SetImageはそのすべてを処理します。

+0

当初、私の機能はあなたが書いたものとまったく同じでした。しかし、頻繁にクラッシュしていました。 DispatchQueue.main.asyncブロックを追加すると、クラッシュ率が低下します。しかし、まだそれは解決されませんでした..あなたの努力をいただきありがとうございます。 @ozzieozumo – RajibTheKing

関連する問題