UIImageView UIKit setImageWithURL memory usage - ios

Trying to debug my app, but my memory keeps increasing .
I have an app that pulls JSON from a web service with AFNetworking. I use UIKit + AFNetworking to load the URL string that I got from the JSON in UIImageView which are in a custom XIB table cell. I use setImageForURL.
When I load new JSON and hence new image URL's, my memory usage jumps by 2-7 mb each time. The old images are replaced in the UI by new ones. Live memory usage goes up and up. I've looked into the arrays holding the JSON and so forth - no leaks.
I suspect there is some image caching going on but I've never seen any information regarding image caching when using UIImageView with setImageWithURL. I've seen memory issues using imageNamed though.
Does setImageWithURL have the same memory issues as imageNamed?

setImageWithURL: from AFNetworking handles the caching of the images downloaded with this method. The next time you call this for the same URL it will check the cache first to see if the image is cached (so no need to go network again).
From AFNetworking API:
Asynchronously downloads an image from the specified URL, and sets it
once the request is finished. Any previous image request for the
receiver will be cancelled. If the image is cached locally, the
image is set immediately, otherwise the specified placeholder image
will be set immediately, and then the remote image will be set once
the request is finished. By default, URL requests have a Accept
header field value of "image / *", a cache policy of
NSURLCacheStorageAllowed and a timeout interval of 30 seconds, and
are set not handle cookies. To configure URL requests differently, use
setImageWithURLRequest:placeholderImage:success:failure:
So there is indeed caching, hence memory usage.
Hope it helps.

Related

Kingfisher how it checks if need to refresh image?

I'm using a Kingfisher lib to manage images. The server refresh image every hour. Kingfisher not refreshing the image. Why?
MY INVESTIGATION: I've read cheat sheet and wiki and found out that the cache is marking as expired after 5 minutes for memory and 7 days for disk. When app did enter background and receive UIApplicationDidEnterBackgroundNotification the library performs backgroundCleanExpiredDiskCache that cleans the disk cache. Also there is a .forceRefresh option to load the image from web every time.
But i don't need to load image every time. I just need to refresh it when the new image appear on the same image url. How this works? I think it should be some field that received from the server, that can tell - you need to update your image, and the lib should manage this field, isn't it?

AlamoFire image memory issue

I use alamofireimage for loading images async and I use AutoPurgingImageCache for caching the loaded images (url request). I have a pull-to-refresh feature in my app and after I do that even if the app content remains the same I see that the app size is increasing and alamofire does not fetch the images from cache and instead it loads them from new requests. Profiling the app reveals that a memory issue exists in alamofire. I have attached the screen shot. I would appreciate if someone has some insight into this.
What cache size did you specify? It's possible that you're experiencing cache misses because the number of distinct images you request per-refresh is more than large enough to fill up the entire cache.
It's also possible that the cache key, i.e. image URL, is changing between refreshes, which could prevent your caching mechanism from correctly looking up cached images.
It's certainly possible there's a problem with AlamoFire, but you should probably start by examining your caching setup for problems like the above.

How to handle memory when many images has to be downloaded?

I have created an app in which users will be able to upload the images and they can also see all the images uploaded by other users. I have integrated the code for the pagination and downloading the 10 images at a time and showing them on the UITableView. I have used AFNetworking for this task which is saving the image in the cache memory. The problem is that when user keeps downloading the images and count goes to around 300 images, app crashes because the device runs out of memory. I am looking for the best solution of this issue. What I have thought is to keep 50 images in the cache at a time and when user downloads the newer images, older ones will be deleted from the cache. Please also let me know if I can do this with AFNetworking.
You should use SDWebImage instead of downloading images it will cache and you can customise that caching option also .
Iam using this SDWebImage for caching 150 +images in UICollectionview and same in UITableview and its work perfect.
Initially we need to add a placeholder then it will appear one by one.
implementation
1.Take out the SDWebImage code
SDWebImage
2.Import the header file in to your viewcontroller
#import <SDWebImage/UIImageView+WebCache.h>
3.then add a single line of code inside cellforrowindex() method. i will gve you example code snaps
// Here we use the new provided setImageWithURL: method to load the web image
[cell.imageView setImageWithURL:[NSURL URLWithString:#"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
Try APSmartStorage. You can manage number of images stored in memory. And if 'memory warning' occurred images will be removed from memory. But anyway it's ok because all images stored in files, so you don't need to reload them from network.
As #Aklesh Rathaur mentioned in comments, you could try SDWebImage, which is also used by Facebook on their mobile app.
It does a pretty good job at caching and freeing memory when more memory is required. Quoting How is SDWebImage better than X?
On the other side, SDWebImage caches the UIImage representation in memory and store the original compressed (but decoded) image file on disk. UIImage are stored as-is in memory using NSCache, so no copy is involved, and memory is freed as soon as your app or the system needs it.
Let us know your results :-)

Configure the delay afnetwork stores images

I want to be able control how much time the image is stored in the cache. This is how i download the image using afnetwork:
[myImageView setImageWithURL:url placeholderImage:placeHolder];
I looked it up in the documentation, i didn't find anything interesting.
any clue?
EDIT: Additional question: is the cache stored in the disk? i guess so because images remain in the cache even after i close the application. but i am not sure.
AFNetworking uses an NSCache instance, which will store more and more images in memory, until a memory warning is received, at which point it will remove some or all of the messages. NSCache does not save to disk.
AFNetworking also uses NSURLCache, which caches URL responses to disk based on (1) your NSURLRequest settings and (2) the cache headers sent by the HTTP server. You can adjust the caching behavior in your app by setting the NSURLRequestCachePolicy, and on your server by setting the cache headers.
If that doesn't give you enough control, you may want to check out SDURLCache, an open source NSURLCache alternative.

what is the default caching behavior of NINetworkImageView in Nimbus for iOS

I was looking at the NINetworkImageView in the Nimbus project and was curious about that the default caching settings are. Once I call setPathToNetworkImage and loads an image, does that go in the global cache? Is it smart enough to realize it's the same image if we create another networkImageView with the same pathToNetworkImage and thus avoid a network request?
Does it store it in memory or disk by default? What are the default cache durations?
Once I call setPathToNetworkImage and loads an image, does that go in the global cache?
Yes. By default it goes into Nimbus' global in-memory image cache. Here's what's going on in the background: once an image loads and before the image is returned to the UI thread the raw image is stored in the disk cache[1]. Once the loading thread returns, the raw image is set to the UIImageView and the raw image is also stored in the in-memory cache.
Is it smart enough to realize it's the same image if we create another networkImageView with the same pathToNetworkImage and thus avoid a network request?
Yes. As long as it has all of the same configurable properties[2] then it will immediately load the image from the in-memory cache, if it exists. You can see how an image's cache key is generated here: https://github.com/jverkoey/nimbus/blob/master/src/networkimage/src/NINetworkImageView.m#L144
[1] This is because storing to the disk is a blocking operation which we do not want to block the UI thread with.
[2] If you have two network image views loading the same url but one has a different content mode then the image will need to be processed twice because the in-memory cache keys will be different. That being said, only the image URL is used for the disk cache key so we will only end up hitting the network once, caching the image, and then for the second network image view loading the image from disk and cropping it with the other content mode.
Aside: it appears that the documentation for the two cache properties is borked, so I will have to fix this.

Resources