K.Wu
K.Wu

Reputation: 3633

Rendering GIF images causes extensive memory usage in Swift?

When I try to render a GIF image (selected from photo library, whose data type is PHAsset), I use the following code:

PHImageManager().requestImageData(for: asset, options: nil) { (data, _, _, _) in
    if let imageData = data {
        imageView.image = UIImage.gif(data: imageData)
    }
}

Where .gif is an extension to UIImage I copied from here, I believe many people use it.

The problem is, when I run the above code, the memory usage rises by about 20+MB, which is not outrageous, however, when I delete this selected GIF asset, the memory usage does not drop. And if I go ahead and select more GIF assets, for each one I select and run the above code, the memory usage rises by 20+MB. Now it's not acceptable anymore as the memory usage will just go up and never drop until the app crashes.

I understand why the memory usage goes up when I render a GIF image, I mean, the image data sits in the memory. What I don't know is how to I deallocate the chunk of memory when I wish to delete the GIF image?

--------------UPDATE-----------------

  1. The UIImageView on "TestScreen" displays the thumbnail of the selected GIF image

  2. When I press the GIF image, the app will open the image in full screen mode and if it's a GIF image, it'll play the animated image by running the above code

  3. The memory goes up and never drops when I repeatedly open the GIF image in full screen

Upvotes: 0

Views: 1550

Answers (1)

Manuel
Manuel

Reputation: 15042

The memory leak may be in your own code rather than in the .gif extension. Maybe the view controller that displays the .gif does not deinitiazile when you close it. Wherever the leak is, here are two ways to find it:

a) A very simple approach is to add a print command to the de-/initialization of your objects. So you can see in the console when an object should be deinitialized and free up memory but in fact doesn't, e.g.:

class MyClass {

   init() { 
      print("init: \(self)")
   }

   deinit { 
      print("deinit: \(self)")
   }
}

b) A more insightful and convenient method is to use Xcode Instruments.

It is a much more powerful way of inspecting the memory management of your app than adding print commands. Also, once you have figured out how to use it, you will love it as it automates a lot of steps and eventually you will be able to check for memory leaks with just a few clicks.

Here you can find a tutorial on how to use Xcode Instruments.

If you post the code for the screen with the black background that opens and displays the GIF it may give a hint what the problem might be. In most cases it is something like a delegate that is not declared weak or another form of circular strong reference.

Upvotes: 2

Related Questions