2022-12-29ios-优化加载本地大图片

这里面使用到了yykit库,首先在podfile里面添加库

pod 'YYKit'

FGAsyncLoadImgUtil.h头文件代码很简单

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN

@interface FGAsyncLoadImgUtil : NSObject
+ (void)asyncLoadImgWithimgName:(NSString *)imgName block:(void(^)(UIImage *image))block;
@end

NS_ASSUME_NONNULL_END

FGAsyncLoadImgUtil.m文件,主要逻辑是通过线程异步加载渲染并缓存至内存来完成

#import "FGAsyncLoadImgUtil.h"
#import "YYKit.h"

@interface FGAsyncLoadImgUtil()

@property(nonatomic, strong) NSOperationQueue *operationQueue;
@property(nonatomic, strong) YYThreadSafeDictionary *safeImgDict;

@end

static FGAsyncLoadImgUtil *asyncLoadImgUtil = nil;

@implementation FGAsyncLoadImgUtil

+ (instancetype)shareInstance
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        asyncLoadImgUtil = [[[self class] alloc] init];
    });
    return asyncLoadImgUtil;
}

- (instancetype)init
{
    if (self = [super init])
    {
        // 根据测试数据以及项目线程控制,自行设置线程数量
        NSInteger queueCount = 6;
        self.operationQueue = [[NSOperationQueue alloc] init];
        self.operationQueue.name = @"com.FGAsyncLoadImgUtil.www";
        self.operationQueue.maxConcurrentOperationCount = queueCount;
        self.safeImgDict = [YYThreadSafeDictionary dictionary];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveMemoryWarning) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
    }
    return self;
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)didReceiveMemoryWarning
{
    [self.safeImgDict removeAllObjects];
}

+ (void)asyncLoadImgWithimgName:(NSString *)imgName block:(void(^)(UIImage *image))block
{
    [[FGAsyncLoadImgUtil shareInstance] asyncLoadImgWithimgName:imgName block:block];
}

- (void)asyncLoadImgWithimgName:(NSString *)imgName block:(void(^)(UIImage *image))block
{
    if (!imgName || imgName.length == 0)
    {
        return;
    }
    UIImage *image = [self.safeImgDict objectForKey:imgName];
    if (image)
    {
        !block ? :block(image);
    }
    else
    {
        __weak typeof(self)wSelf = self;
        [self.operationQueue addOperationWithBlock:^{
            __strong typeof(wSelf) strongSelf = wSelf;
            UIImage *image = [FGAsyncLoadImgUtil _getDrawImageByName:imgName];
            if (image)
            {
                UIImage *storeImage = [strongSelf.safeImgDict objectForKey:imgName];
                if (!storeImage)
                {
                    [strongSelf.safeImgDict setObject:image forKey:imgName];
                }
                else
                {
                    image = storeImage;
                }
                if (block)
                {
                    dispatch_async(dispatch_get_main_queue(), ^{
                        block(image);
                    });
                }
            }
        }];
    }
}

+ (UIImage *)preDrawImageWithName:(NSString *)name
{
    NSString *imgName = nil;
    UIImage *img = nil;
    if (!name || name.length == 0)
    {
        return img;
    }
    if (3 == [UIScreen mainScreen].scale)
    {
        imgName = [NSString stringWithFormat:@"%@@3x.png",name];
        img = [FGAsyncLoadImgUtil _preDrawImageWithName:imgName];
    }
    if (img==nil)//没有3x图,可以尝试获取2x图片
    {
        imgName = [NSString stringWithFormat:@"%@@2x.png",name];
        img = [FGAsyncLoadImgUtil _preDrawImageWithName:imgName scale:2.0];
        if (img == nil)
        {
            imgName = [NSString stringWithFormat:@"%@.jpeg",name];
            img = [FGAsyncLoadImgUtil _preDrawImageWithName:imgName scale:1.0];
        }
    }
    return img;
}

+ (UIImage *)_preDrawImageWithName:(NSString *)imgName
{
    NSString *imgPath = [[NSBundle mainBundle].resourcePath stringByAppendingPathComponent:imgName];
    NSData *data = [NSData dataWithContentsOfFile:imgPath];
    if (data)
    {
        UIImage *image = [[UIImage alloc] initWithData:data scale:[UIScreen mainScreen].scale];
        image = [image imageByDecoded];
        return image;
    }
    else
    {
        return nil;
    }
}

/**
 根据指定的scale加载图片
 */
+ (UIImage *)_preDrawImageWithName:(NSString *)imgName scale:(CGFloat)scale
{
    NSString *imgPath = [[NSBundle mainBundle].resourcePath stringByAppendingPathComponent:imgName];
    NSData *data = [NSData dataWithContentsOfFile:imgPath];
    if (data)
    {
        UIImage *image = [[UIImage alloc] initWithData:data scale:scale];
        image = [image imageByDecoded];
        return image;
    }
    else
    {
        return nil;
    }
}


+ (UIImage *)_getDrawImageByName:(NSString *)imgName
{
//    NSString *imgPath = [[NSBundle mainBundle].resourcePath stringByAppendingPathComponent:imgName];
    NSData *data = [NSData dataWithContentsOfFile:imgName];
    if (data)
    {
        UIImage *image = [[UIImage alloc] initWithData:data scale:[UIScreen mainScreen].scale];
        image = [image imageByDecoded];
        return image;
    }
    else
    {
        return nil;
    }
}
@end

最后是调用,调用很简单,在block回调里面设置图片

    [FGAsyncLoadImgUtil asyncLoadImgWithimgName:self.localPath block:^(UIImage * _Nonnull image) {
        [self.backGroundImage setImage:image];
    }];
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容