0

Oddly I can't find anything on this topic anywhere.

Basically, I have a simple UITableView with, lets say, 10 rows. Each row has a user associated with it, and each user has a "profile picture". Now lets say that each row was created by 1 of 2 users, so it will be displaying 1 of 2 different profile pictures in each of the rows.

I'm trying to be memory efficient, so I don't want to load the same image 5 times in a new UIImageView. So I tried using the exact same UIImageView reference in each of the rows for the same user, but it seems that only the last row to get loaded shows the ImageView. If, for example, a row that was offscreen becomes visible and reloads, the image will then appear for that row and disappear from the row where it was previously appearing.

So my question is, how can I do this?

A. A solution to what I'm trying to do/something I'm missing

B. IOS will not load the same image into memory AGAIN if I use it in a new UIImageView, so I'm just wasting my time worrying about this

C. A new solution that blows my mind

Thanks!

Steve

*Note, I'm building this in Xamarin/Mono but I don't think C# vs Objective C would make a difference in this case

Steve Lobdell
  • 383
  • 3
  • 9
  • 2
    A view can only have one superview, so adding it as a subview to a second cell will remove it from the original one. – dan Jun 24 '15 at 18:43

2 Answers2

2

UIImage has a built-in cache, so option B is most likely your solution. Because of this cache, there is probably no need to keep a single UIImage instance around to use in each UIImageView. While that approach may speed up your application slightly, it's more likely a case of premature optimization.

In addition, UITableView is highly optimized to reuse cells that move off screen so you will only ever have as many UIImageView instances as you have visible UITableViewCells.

Your problem was caused by the fact that UIViews can only have at most one superview at a time. So every time you added your single instance to a cell, it removed itself from the previous cell. That's why you only saw it on the very last cell.

ndmeiri
  • 4,979
  • 12
  • 37
  • 45
  • See this question for more information on the `UIImage` cache. http://stackoverflow.com/questions/8270277/does-uiimageview-cache-images – ndmeiri Jun 24 '15 at 18:55
0

I think you are misunderstanding how iOS draws images. You are going to need to create multiple UIImageViews in every spot the image is displayed, but you can (and should) reuse your UIImage object, and that's what really consumes memory.

So in your cellForRowAtIndexPath method, simply create an imageView and set it to the image which you've already loaded.

Reuse images, not imageViews.

scott
  • 1,194
  • 7
  • 18
  • This was my original idea, but here's my issue. If the image is not already saved locally, I'm downloading it asynchronously. So my table loads all the rows, then when then image is downloaded it needs to stuff the image into the imageview of all the rows that will display that image. If I use the same Image(blank) for each imageview, when I update the image after its downloaded, it'll be a new image and will no longer be referenced by the imageviews. Sorry, I may be thinking so hard I'm confusing myself. – Steve Lobdell Jun 24 '15 at 19:58
  • I see your problem. Is the image really that big? I wouldn't load a single image asynchronously. – scott Jun 24 '15 at 20:01
  • It's really not the size of the image, it's how many there are. So a normal scenario might be 1 or 2 because after downloading the first time I save them locally. But say someone deletes my app and reinstalls it. They will have to redownload all the images at once. The images are small but it already takes about 2 seconds to retrieve user data from my service and I don't want to big it down any more than that. Trying to slim it down. EDIT: by retrieval I mean a login process which is where this would need to happen. – Steve Lobdell Jun 24 '15 at 20:06
  • Maybe I'll send a notification when the image arrives and any living table row can just re grab the image. – Steve Lobdell Jun 24 '15 at 20:11
  • Thanks for your input Scott. I ended up sharing the UIImage between all UIImageViews showing the same user image, like you suggested. Once an image finishes downloading async I'm just posting a notification with that username so any table row that's showing the image for that user will just update it's UIImageView to the new image that was just downloaded. – Steve Lobdell Jun 25 '15 at 01:57