UIImage memory

Does reloading new images into a UIImage view increase the memory usage each time a new image is loaded, thus potentially leading to a memory leak? If so, then do I need to release the memory used for the currently loaded image before reloading the UIImage with a new image?

Replies

Images called with named: may be kept in cache, hence using memory.


I found this interesting discussion on the matter:

h ttps://www.hackingwithswift.com/read/30/6/fixing-the-bugs-running-out-of-memory


There's probably a simpler way, by setting image to nil, as described here:

https://stackoverflow.com/questions/17666679/uiimageview-not-releasing-memory-according-to-vm-tracker-low-memory-warnings

>>There's probably a simpler way, by setting image to nil, as described here:

Does this mean I should set the UIImage "image" to nil right before loading any new image like the following?



Does the same memory issue occur when setting images on Buttons (instead of UIImages) as well with the following?


setImage(UIImage(named: myButtonImageFile), for: .normal)

>>There's probably a simpler way, by setting image to nil, as described here:

Does this mean I should set the UIImage "image" to nil right before loading any new image like the following?

Yes, that's what I understand (that should flush the cache). But I didn't test.

Did you test ? What is the result ?


Does the same memory issue occur when setting images on Buttons (instead of UIImages) as well with the following?

setImage(UIImage(named: myButtonImageFile), for: .normal)

I suppose so, because it is linked to UIImage(named:)

I will update my code to always set the image to NIL before setting a new image (see below) and let you know:


myButton.setImage(nil, for: .normal)
myButton.setImage(UIImage(named: myNewButtonImageFile), for: .normal)



In my card game application I am seeing memory constantly increase throughout the game. Since there is only 52 different card images which can be displayed throughout the game, I would expect the memory to "level-out" eventually once all various card images have been loaded one time. I was just concerned whether reloading the same card images over and over into Button or UIImage views, while playing multiple rounds of cards, would keep increasing the memory footprint. This is why I wondered if constantly loading new images into UIViews (and Buttons) would cause memory to keep increasing even if the image was loaded once before.

What could happen is that when you reload you create a new instance (another object), without freeing the previous one.


One way to check is to add a print(theUIImageView) for a specific object (card 0 for instance) and see if you alsways call the same or create new instances.and check

I toggled my "mute button", which switches images back and forth (mute/unmute/mute/etc.) and then used "print" to display the "mute_button" view object after each time the image was reloaded to the new image. The output is below. It seems the addresses stay the same


<print output not allowed to be displayed ... since "It is being moderated" for some reason>


I cannot figure out how to set an UIImage view to NIL before reloading .... any ideas?

What is the print statement ?

It should be print(myButton)


If it is different each time, to set to nil, I would

- have a property as

var buttonImage : UIImage?


then

buttonImage = nil
buttonImage = UIImage(named: myNewButtonImageFile)
myButton.setImage(buttonImage for: .normal)

1) With the code below, I see the following output print statements


print("mute_Button = \(String(describing: mute_Button))")
mute_Button.setImage(UIImage(named: muteOffImageFile), for: .normal)


print output not allowed to be displayed ... since It is "Currently Being Moderated" for some reason. Always happens .. UGH



2) To set a UIButton image to NIL before reloading I am doing the following:


mute_Button.setImage(nil, for: .normal) 
mute_Button.setImage(UIImage(named: muteOffImageFile), for: .normal)


3) To set a UIImage image to NIL before reloading I am doing the following: Is this correct?


imageObj.image = UIImage(contentsOfFile: "") 
imageObj.image = UIImage(named: imageFile)

I don't want to see the description, but the object instance itself:

priint(mute_Button)

The following print statement in my code displays text which I cut and pasted into this post. However, the post now states it is "currently being moderated" for some reason so I guess you cannot see it. I had to remove the print output so I could post this response


print("mute_Button = \(mute_Button)")

It is very frustrating that posts indicate "currently being moderated" when there is nothing visually wrong with the text I am including

I tried manually retying all the text output by hand by still "currently being moderated"


I have no idea how to show you the text output, sorry


Can you please let me know how you would set a UIImage (not UIButton) to NIL?

>>I don't want to see the description, but the object instance itself:

print(mute_Button)


This print statement displays a long hex value for the UIButton. This seems to be the actual address of the UIButton itself since this address does not change when I switch the button image. The print statement also prints out "frame, opaque, autoresize and layer " data as well.


It does not seem like the actual UIButton instance (address) is changing when I reload images.


Do you think UIImage image would act the same way?



To set a UIImage image to NIL before reloading I am doing the following: Is this correct?


imageObj.image = UIImage(contentsOfFile: "")
imageObj.image = UIImage(named: imageFile)

Try adding some spaces in the text that requires moderation ; it it is an URL, it is always moderated (except SO, apple URL) ; change to

h ttps or w ww

there is no url or www it is just normal text as far as I can see.


toggling the MUTE button in my application causes the following print statments to be displayed :


Finally figure out the issue was with the <number> ... see below


I cannot provide the 12-digit <number> below since it will be moderated if I include it


mute_Button = Optional(<UIButton <number> frame = (324 35; 35 35); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x603000132fd0>>)

mute_Button = Optional(<UIButton <number> frame = (324 35; 35 35); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x603000132fd0>>)

mute_Button = Optional(<UIButton <number> frame = (324 35; 35 35); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x603000132fd0>>)

mute_Button = Optional(<UIButton <number> frame = (324 35; 35 35); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x603000132fd0>>)

mute_Button = Optional(<UIButton <number> frame = (324 35; 35 35); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x603000132fd0>>)



<number> = 0 x 6 1 7 0 0 0 0 8 0 3 8 0