Use the memory bytes size, instead of pixel size to calculate the memory cost function
This commit is contained in:
parent
b866c6aa97
commit
6dd92d11ff
|
@ -11,6 +11,8 @@
|
|||
#import "SDImageCoder.h"
|
||||
#import "SDImageCodersManager.h"
|
||||
#import "SDImageFrame.h"
|
||||
#import "UIImage+MemoryCacheCost.h"
|
||||
#import "objc/runtime.h"
|
||||
|
||||
static CGFloat SDImageScaleFromPath(NSString *string) {
|
||||
if (string.length == 0 || [string hasSuffix:@"/"]) return 1;
|
||||
|
@ -426,3 +428,31 @@ static NSArray *SDBundlePreferredScales() {
|
|||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface SDAnimatedImage (MemoryCacheCost)
|
||||
|
||||
@end
|
||||
|
||||
@implementation SDAnimatedImage (MemoryCacheCost)
|
||||
|
||||
- (NSUInteger)sd_imageMemoryCost {
|
||||
NSNumber *value = objc_getAssociatedObject(self, @selector(sd_memoryCost));
|
||||
if (value != nil) {
|
||||
return value.unsignedIntegerValue;
|
||||
}
|
||||
|
||||
CGImageRef imageRef = self.CGImage;
|
||||
if (!imageRef) {
|
||||
return 0;
|
||||
}
|
||||
NSUInteger bytesPerFrame = CGImageGetBytesPerRow(imageRef) * CGImageGetHeight(imageRef);
|
||||
NSUInteger frameCount = 1;
|
||||
if (self.isAllFramesLoaded) {
|
||||
frameCount = self.animatedImageFrameCount;
|
||||
}
|
||||
frameCount = frameCount > 0 ? frameCount : 1;
|
||||
NSUInteger cost = bytesPerFrame * frameCount;
|
||||
return cost;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -82,13 +82,14 @@ typedef NS_ENUM(NSUInteger, SDImageCacheConfigExpireType) {
|
|||
@property (assign, nonatomic) NSUInteger maxCacheSize;
|
||||
|
||||
/**
|
||||
* The maximum "total cost" of the in-memory image cache. The cost function is the number of pixels held in memory.
|
||||
* The maximum "total cost" of the in-memory image cache. The cost function is the bytes size held in memory.
|
||||
* @note The memory cost is bytes size in memory, but not simple pixels count. For common ARGB8888 image, one pixel is 4 bytes (32 bits).
|
||||
* Defaults to 0. Which means there is no memory cost limit.
|
||||
*/
|
||||
@property (assign, nonatomic) NSUInteger maxMemoryCost;
|
||||
|
||||
/**
|
||||
* The maximum number of objects the cache should hold.
|
||||
* The maximum number of objects in-memory image cache should hold.
|
||||
* Defaults to 0. Which means there is no memory count limit.
|
||||
*/
|
||||
@property (assign, nonatomic) NSUInteger maxMemoryCount;
|
||||
|
|
|
@ -11,12 +11,13 @@
|
|||
@interface UIImage (MemoryCacheCost)
|
||||
|
||||
/**
|
||||
The memory cache cost for specify image used by image cache. The cost function is the pixles count held in memory.
|
||||
The memory cache cost for specify image used by image cache. The cost function is the bytes size held in memory.
|
||||
If you set some associated object to `UIImage`, you can set the custom value to indicate the memory cost.
|
||||
|
||||
For `UIImage`, this method return the single frame pixles count when `image.images` is nil for static image. Retuen full frame pixels count when `image.images` is not nil for animated image.
|
||||
For `NSImage`, this method return the single frame pixels count because `NSImage` does not store all frames in memory.
|
||||
For `UIImage`, this method return the single frame bytes size when `image.images` is nil for static image. Retuen full frame bytes size when `image.images` is not nil for animated image.
|
||||
For `NSImage`, this method return the single frame bytes size because `NSImage` does not store all frames in memory.
|
||||
@note Note that because of the limitations of categories this property can get out of sync if you create another instance with CGImage or other methods.
|
||||
@note For custom animated class conforms to `SDAnimatedImage`, you can override this getter method in your subclass to return a more proper value instead, which representing the current frames' total bytes.
|
||||
*/
|
||||
@property (assign, nonatomic) NSUInteger sd_memoryCost;
|
||||
|
||||
|
|
|
@ -8,14 +8,22 @@
|
|||
|
||||
#import "UIImage+MemoryCacheCost.h"
|
||||
#import "objc/runtime.h"
|
||||
#import "NSImage+Compatibility.h"
|
||||
|
||||
FOUNDATION_STATIC_INLINE NSUInteger SDMemoryCacheCostForImage(UIImage *image) {
|
||||
CGImageRef imageRef = image.CGImage;
|
||||
if (!imageRef) {
|
||||
return 0;
|
||||
}
|
||||
NSUInteger bytesPerFrame = CGImageGetBytesPerRow(imageRef) * CGImageGetHeight(imageRef);
|
||||
NSUInteger frameCount;
|
||||
#if SD_MAC
|
||||
return image.size.height * image.size.width;
|
||||
frameCount = 1;
|
||||
#elif SD_UIKIT || SD_WATCH
|
||||
NSUInteger imageSize = image.size.height * image.size.width * image.scale * image.scale;
|
||||
return image.images ? (imageSize * image.images.count) : imageSize;
|
||||
frameCount = image.images.count > 0 ? image.images.count : 1;
|
||||
#endif
|
||||
NSUInteger cost = bytesPerFrame * frameCount;
|
||||
return cost;
|
||||
}
|
||||
|
||||
@implementation UIImage (MemoryCacheCost)
|
||||
|
|
Loading…
Reference in New Issue