Any way to get a Cached UIImage from my 'Documents' directory?

后端 未结 4 1363
既然无缘
既然无缘 2021-02-04 17:58

I know that the -imageNamed: method returns a Cached UIImage, but the problem is that my image file is stored in \'Documents\', and the -imageNamed: method seems to only search

相关标签:
4条回答
  • 2021-02-04 18:22

    I made an extension of the answer provided by rpetrich and overrode the imageName: method to add more of a drop in replacement. It searches the main bundle first and then looks in the caches directory. You could of course change the caches directory to the document directory.

    @interface UIImage (CacheExtensions)
    + (UIImage *)imageNamed:(NSString *)name;
    + (void)clearCache;
    @end
    
    #import "UIImage+CacheExtensions.h"
    
    static NSMutableDictionary *UIImageCache;
    
    @implementation UIImage (CacheExtensions)
    
    + (UIImage *)imageNamed:(NSString *)name 
    {
        id result;
        if (!UIImageCache)
            UIImageCache = [[NSMutableDictionary alloc] init];
        else {
            result = [UIImageCache objectForKey:name];
            if (result) return result;
        }
    
        // First, check the main bundle for the image
        NSString *imagePath = [[NSBundle mainBundle] pathForResource:name ofType:nil];
    
        result = [UIImage imageWithContentsOfFileimagePath];
        if(result) {
            [UIImageCache setObject:result forKey:name];
            return result;
        }
    
        // If not found, search for the image in the caches directory
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); 
        NSString *cachesImagePath = [[paths lastObject] stringByAppendingPathComponent:name];
    
        result = [UIImage imageWithContentsOfFile:cachesImagePath];
        if(result) {
            [UIImageCache setObject:result forKey:name];
            return result;
        }
    
        return nil;
    }
    
    + (void)clearCache
    {
        [UIImageCache removeAllObjects];
    }
    
    @end
    
    0 讨论(0)
  • You can cache UIImages yourself just as -imageNamed: does. It just loads them, and then holds onto them. You can hold onto them, too, using an NSDictionary and implement your own -imageNamed:

    But I'm more concerned about the trouble you're having with scaling. How are your images getting into Documents, how are you scaling them, and have you tested the same image file stored in the bundle? I doubt that -imageNamed: has anything to do with this. I would more suspect things like the fact that the bundle has some compression applied to it (though I don't yet have a theory on why this would matter in practice), differences in the file, or differences in how the rest of the program is behaving during scaling (causing contention on the disk or CPU). Caching is unlikely related to this issue.

    I'd do some profiling w/ Instruments to try to find out where the choppiness is coming from. Are you maxing out the disk, CPU, memory? What's the bottleneck?

    0 讨论(0)
  • 2021-02-04 18:41

    What about writing your own image cache? You have all the pieces in place, now you just need to encapsulate it and keep a record of images you've already loaded.

    0 讨论(0)
  • 2021-02-04 18:43

    The simplest way would be an NSMutableDictionary storing the cached images and a clear cache method:

    @interface UIImage (CacheExtensions)
    + (id)cachedImageWithContentsOfFile:(NSString *)path;
    + (void)clearCache;
    @end
    
    static NSMutableDictionary *UIImageCache;
    
    @implementation UIImage (CacheExtensions)
    + (id)cachedImageWithContentsOfFile:(NSString *)path
    {
        id result;
        if (!UIImageCache)
            UIImageCache = [[NSMutableDictionary alloc] init];
        else {
            result = [UIImageCache objectForKey:path];
            if (result)
                return result;
        }
        result = [UIImage imageWithContentsOfFile:path];
        [UIImageCache setObject:result forKey:path];
        return result;
    }
    + (void)clearCache
    {
        [UIImageCache removeAllObjects];
    }
    @end
    

    Note: you should call +[UIImage clearCache] from your didReceiveMemoryWarning method. Also, clearCache will invalidate all objects in the cache, not just unused items; a UIImage subclass and more complicated caching mechanism would be required to remedy this.

    0 讨论(0)
提交回复
热议问题