2017-12-10 8 views
1

SOおよび他の記事(下記参照)の回答を読んだあと、複数のイメージをアニメーションアレイにロードする際に、 ?ここでUIImage - Swift 3.0を使用するとキャッシュをフラッシュしてメモリを解放する方法

http://www.alexcurylo.com/2009/01/13/imagenamed-is-evil/

私の目標です:

  1. アニメーションは、フラッシュキャッシュを果たし、他のアニメーション(繰り返し、洗い、すすぎ、あなたをロードした後、アニメーション・アレイ(以下のコードを参照してください)
  2. を作成します。それを得る:)

Appleは https://forums.developer.apple.com/thread/17888

を述べたよう

UIImage(named: imageName)を使用すると、画像がキャッシュされますが、私の場合、行を2〜3回アニメーション再生した後、iOSはアプリケーションを終了します(OSは低メモリ警告に応答せず、アプリケーションを終了します)

私は、画像をキャッシュしたくないと、むしろ我々は可能性が次のいずれか

  1. がメモリにアニメーションが完了するたびにフラッシュしてから、新しいアニメーションをロードします。ここでは、新たなシーン

へのユーザー移行が私のコードであるとき、または

  • フラッシュメモリは:SOの応答に基づいて

    // create the Animation Array for each animation 
    
    func createImageArray(total: Int, imagePrefix: String) -> [UIImage]{ 
        var imageArray: [UIImage] = [] 
        for imageCount in 0..<total { 
         let imageName = "\(imagePrefix)-\(imageCount).png" 
         let image = UIImage(named: imageName)! // here is where we need to address memory and not cache the images 
    
         //let image = UIImage(contentsOfFile: imageName)! // maybe this? 
    
         imageArray.append(image) 
        } 
        return imageArray 
    } 
    
    
    // here we set the animate function values 
    
    func animate(imageView: UIImageView, images: [UIImage]){ 
        imageView.animationImages = images 
        imageView.animationDuration = 1.5 
        imageView.animationRepeatCount = 1 
        imageView.startAnimating() 
    } 
    
    // Here we call the animate function 
    
    animation1 = createImageArray(total: 28, imagePrefix: "ImageSet1") 
    animation2 = createImageArray(total: 53, imagePrefix: "ImageSet2") 
    animation3 = createImageArray(total: 25, imagePrefix: "ImageSet3") 
    
    func showAnimation() { 
        UIView.animate(withDuration: 1, animations: { 
         animate(imageView: self.animationView, images: self.animation1) 
    
         }, completion: { (true) in 
    
         //self.animationView.image = nil // Maybe we try the following? 
         //self.animationView.removeFromSuperview() 
         //self.animationView = nil 
    
         }) 
        } 
    

    これは防ぐ最良の方法であってもよいように、それが見えます以下からの画像がキャッシュされているが、私のコードで動作するようには思えません。私もこれを試してみました

    let image = UIImage(contentsOfFile: imageName)! 
    

    が、どちらか動作していないよう:

    func applicationDidReceiveMemoryWarning(application: UIApplication) { 
        NSURLCache.sharedURLCache().removeAllCachedResponses() 
    } 
    

    (上記の私のコードを参照してください)私はまた、完了ブロックには、次の資料(removeFromSuperview)を試してみましたが、私は、これはどちらかの仕事を得ることができませんでした:

    https://www.hackingwithswift.com/example-code/uikit/how-to-animate-views-using-animatewithduration

    新しいコード:

    // create the Animation Array for each animation 
    
    func createImageArray(total: Int, imagePrefix: String) -> [UIImage]{ 
        var imageArray: [UIImage] = [] 
        for imageCount in 0..<total { 
         let imageName = "\(imagePrefix)-\(imageCount).png" 
         //let image = UIImage(named: imageName)! // replaced with your code below 
    
        if let imagePath = Bundle.mainBundle.path(forResource: "ImageSet1" ofType: "png"), 
        let image = UIImage(contentsOfFile: imagePath) { 
         //Your image has been loaded } 
    
         imageArray.append(image) 
        } 
        return imageArray } 
    
  • +0

    は、あなたが言う:「私のコードで動作するようには思えません」。どういう意味ですか?あなたはまだ解雇されていますか?あなたはアニメーションを見ることができませんか? –

    +0

    こんにちは@AndreaMugnaini - 私は様々な記事から提案された答えを試しました(//でマークされたコメントを参照)。はい、私はまだ終了しています。アニメーションは完璧に機能しますが、アニメーションを追加するごとに全体のメモリ使用量が増えます。私は単にself.animationView.removeFromSuperview()を使ってアニメーションをフラッシュすることができると思ったが、これはどちらもうまく動作していなかった(メモリは同じままである)。これはあなたのpngファイルのサイズを確認してください –

    +0

    を明確にするのに役立ちますか? –

    答えて

    2

    これはかなり簡単です。 UIImage(named:)イメージをキャッシュし、UIImage(contentsOfFile:)はキャッシュしません。

    画像をキャッシュしない場合は、代わりにUIImage(contentsOfFile:)を使用してください。それをうまく動作させることができない場合は、コードを投稿すると、デバッグに役立ちます。

    UIImage(contentsOfFile:)は、アプリケーションバンドル内のファイルを検索しないことに注意してください。イメージファイルへのフルパスが必要です。あなたは、ファイルへのパスを見つけることがBundleメソッドを使用して、UIImage(contentsOfFile:)にそのパスを渡す必要があります:あなたのコードでは、画像の配列にすべての3つのアニメーションのためのすべての画像をロードし、それらを解放することはありません

    if let imagePath = Bundle.mainBundle.path(forResource: "ImageSet1" ofType: "png"), 
        let image = UIImage(contentsOfFile: imagePath) { 
        //Your image has been loaded 
    } 
    

    、システムがそれらのイメージをキャッシュするという事実は、かなり無関係のようです。低メモリ状態では、システムはキャッシュされたイメージのコピーをフラッシュする必要がありますが、コードは配列内のすべてのイメージを保持しているので、メモリは解放されません。システムのイメージキャッシュではなく、メモリの問題を引き起こすのはあなたのコードだと私は思っています。

    あなたのコードは次のようになります。

    func createImageArray(total: Int, imagePrefix: String) -> [UIImage]{ 
        var imageArray: [UIImage] = [] 
        for imageCount in 0..<total { 
         let imageName = "\(imagePrefix)-\(imageCount)" 
         if let imagePath = Bundle.main.path(forResource: imageName, 
          ofType: "png"), 
          let image = UIImage(contentsOfFile: imagePath) { 
           imageArray.append(image) 
         } 
        } 
        return imageArray 
    } 
    
    +0

    いいえ。私はそれを仕事に残すつもりです。私はSOの答えにコピー貼り付け可能なコードを提供していません。私の答えをあなたのコードに適応させると、もっと学びます。 –

    +0

    メモリを解放するには、イメージの配列を解放する必要があります。配列はイメージへの強い参照を保持しているので、あなたのメモリフットプリントはダウンしていません。 –

    +0

    あなたの質問を編集して、新しい 'UIImage(contentsOfFile:)'の変更を最後に表示してください。あなたが記述したエラーは、あなたのコードが値ではなくクロージャを返すように書かれているように思えます。 –

    関連する問題