HiveBrain v1.2.0
Get Started
← Back to all entries
patternswiftMinor

Caching image in memory or on disk

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
diskcachingimagememory

Problem

I am caching an image locally..That same image will be used in few screens. Steps for doing this is as follows:

-
Get image from cache

-
If not present in NSCache, get image from Cache directory

-
If not present in Cache Directory, download from Internet

-
Save downloaded image to dir

-
Insert the image in cache

//Helper class is as

class ImageCacheHelper:NSObject{

        static var cache = NSCache()
        static var isNotRunningDispatch:Bool = true

      class func setObjectForKey(imageData:NSData,imageKey:String){

            ImageCacheHelper.cache.setObject(imageData, forKey: imageKey)

        }

      class func getObjectForKey(imageKey:String)->NSData?{

            return ImageCacheHelper.cache.objectForKey(imageKey) as? NSData

        }

      class func getImage(imageUrl:String,completionHandler:(NSData)->()){        
            if ImageCacheHelper.isNotRunningDispatch{

                ImageCacheHelper.isNotRunningDispatch = false
                dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), {
                    let imgUrl = NSURL(string:imageUrl)
                    let imageData = NSData(contentsOfURL: imgUrl!)!
                    ImageCacheHelper.setObjectForKey(imageData, imageKey: "\(imageUrl.hashValue)")
                    ImageCacheHelper.isNotRunningDispatch = true
                    completionHandler(imageData)

                })
            }else{
               print("alerady started loading image")
           }
        }
      }


//How i call this from ViewController class is as

```
let userImageUrl = "\(appBaseUrl)\(imageUrlString)"
let fileManager = NSFileManager.defaultManager()
let diskPaths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.CachesDirectory, NSSearchPathDomainMask.UserDomainMask, true)
let cacheDirectory = diskPaths[0] as NSString
let diskPath = cacheDirectory.stringByAppendingPathComponent("\(userImageUrl.hashValue)")
if let data = ImageCacheHelper.

Solution

Modify Caching Strategy

It seems every image that is subject to caching is ending up both in memory and on disk. Depending on the number of images and caching aggressiveness, this could be more expensive (in terms of resource usage) than the network request used to retrieve the image.

From my perspective, using both NSCache and the Cache directory together doesn’t add any value. They are both volatile and unpredictable (to different extents). The system could reclaim space from either when it deems it necessary.

From Apples File System Programming Guide:


"Note that the system may delete the Caches/ directory to free up disk space, so your app must be able to re-create or download these files as needed.”

Therefore its either a choice between caching in memory and caching on disk or an emphasis of one over the other. This inevitably leads to additional questions about how your app will be used and the what kind of images you are working with.

Some basic guidelines:

  • You don’t want to store a large number of full resolution images in memory



  • You don’t want to have too many file system I/O operations (spread over time)



  • You don’t want to have images in memory that are not going to be seen by the user



  • You don’t want to go to disk every time for frequently seen images



What is a large number? How much is too many? You will have to test and measure.

Test & Measure (and then measure again)

I would definitely recommend testing and measuring your caching strategy to see how much of an impact it has. Xcode instruments provides tools to accomplish this.

One way to go about this is:

  • Test with no cache (this will be your baseline)



  • Test with a simple caching strategy (maybe just using NSCache or the Cache directory)



  • Compare the results of step 2 to your baseline obtained from step 1



  • Not satisfied, then apply a different caching strategy. Repeat step 3. Otherwise, if you are satisfied with the resource usage and responsiveness of the app then you can stop here until there are significant changes to either your codebase, data or the iOS frameworks.

Context

StackExchange Code Review Q#115908, answer score: 3

Revisions (0)

No revisions yet.