Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【IOS开发进阶系列】APP性能优化专题

【IOS开发进阶系列】APP性能优化专题

作者头像
江中散人_Jun
发布于 2023-10-16 03:36:25
发布于 2023-10-16 03:36:25
3750
举报

1 优化资源文件

        在iOS本地资源文件编译后放置与应用程序包(Bundle)文件中即<应用名>.app文件。

NSBundle *bundle = [NSBundle mainBundle];

NSString *plistPath = [bundle pathForResource:@"team" ofType:@"plist"];

1.1    声音格式优化

1.1.1  iOS平台主要的音频文件格式

        WAV文件,WAV文件格式是一种由微软和IBM联合开发的用于音频数字存储的标准,WAV文件的格式灵活,可以储存多种类型的音频数据。由于文件较大不太适合于移动设备这些存储容量小的设备。

        MP3(MPEG Audio Layer 3)文件,是现在非常流行,MP3是一种有损压缩格式,它尽可能地去掉人耳无法感觉的部分和不敏感的部分。

        CAFF(Core Audio File Format)文件,是苹果开发的专门用于Mac OSX和iOS系统无压缩音频格式。它被设计来替换老的WAV格式。

        AIFF(Audio Interchange File Format)文件,是苹果开发的专门用于Mac OS X系统,是专业的音频文件格式。AIFF的压缩格式是AIFF-C(或AIFC),将数据以4:1压缩率进行压缩,应用于Mac OS X和iOS系统。

1.1.2  背景音乐优化

        文件应该比较小,压缩文件是不错的选择,压缩文件主要是AIFC和MP3可以选择,没有特殊情况我们一定要首选AIFC格式,因为这是苹果推荐的格式。

        原始文件格式不一定是AIFC,这种情况下我们需要使用afconvert工具转换为AIFC格式:

$ afconvert -f AIFC -d ima4 Fx08822_cast.wav

1.1.3  音乐特效优化

        音乐特效很多应用游戏中,当发射子弹、敌人被打死和按钮点击等发出的声音,这些声音都是比较短的,

        如果追求震撼的3D效果,可以采用苹果专用无压缩CAFF格式文件,其它格式的文件尽量不要考虑。

$ afconvert -f caff -d LEI16 Fx08822_cast.wav

1.2    图片格式优化

创建UIImage对象方法的优化

+ imageNamed:类级构造方法,方法会在内存中建立缓存,这些缓存直到应用停止才清除,如果是贯穿于整个应用的图片(如图:图标、logo等)推荐使用。

-initWithContentsOfFile: 实例构造方法,如果是使用一次就基本上不再使用的图片推荐使用该方法。

NSString *path = [[NSBundle mainBundle] pathForResource:@"animal-2" ofType:@"png"];

UIImage *image = [[UIImage alloc] initWithContentsOfFile:path];

... ...

[image release];

// MRR情况下调⽤用

1.3    图片裁切

1.3.1  UIImage自定义绘制的四种方法

///方法中会自动做缩放处理

+(void) getBitmapImage:(UIImage *)image Size:(CGSize)imageSize WithCompletionBlock:(HJCallbackBlock)block

{

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        UIGraphicsBeginImageContextWithOptions(imageSize, YES, 0);

        CGContextRef context = UIGraphicsGetCurrentContext();

        if (!context) {

            dispatch_async(dispatch_get_main_queue(), ^{

                block(image);

            });

        }

        CGRect rect = CGRectMake(0, 0, imageSize.width, imageSize.height);

        //坐标系统已经自动考虑了缩放因素,不需要额外处理

        [image drawInRect:rect blendMode:kCGBlendModeNormal alpha:1];

        UIImage *temp = UIGraphicsGetImageFromCurrentImageContext();

        NSData *tempData = UIImageJPEGRepresentation(temp, 1);

        UIGraphicsEndImageContext();

        //设置SDWebImage库的缓存

        NSString *device = [MDUtility getCurrentDeviceModel];

        if ([device rangeOfString:@"iPhone 4"].length > 0) {

            if (tempData.length > 500000) {

                tempData = UIImageJPEGRepresentation(temp, 0.4);

            }

            temp = [UIImage imageWithData:tempData];

        }

        dispatch_async(dispatch_get_main_queue(), ^{

            if (block) {

                block(temp);

            }

        });

    });

    //    //改进方案1

    //        CGImageRef imgRef = CGImageCreateWithImageInRect(image.CGImage,CGRectMake(0, 0, image.size.width, image.size.height));

    //        UIGraphicsBeginImageContextWithOptions(imageSize, YES, 0);

    //        CGContextRef context = UIGraphicsGetCurrentContext();

    //        CGContextDrawImage(context, imageRect, imgRef);

    //        UIImage *imgData = UIGraphicsGetImageFromCurrentImageContext();

    //        UIGraphicsEndImageContext();

    //        CGImageRelease(imgRef);

    //        UIImage *data = [self verticallyFlipImage: imgData];

    //        return data;

    //方案二,内存有释放,挂机

    //    UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);

    //    CGContextRef context = UIGraphicsGetCurrentContext();

    //    CGRect rect = CGRectMake(0, 0, imageSize.width * [UIScreen mainScreen].scale, imageSize.height * [UIScreen mainScreen].scale);

    //    // draw alpha-mask

    //    CGContextDrawImage(context, rect, image.CGImage);

    //    // draw tint color, preserving alpha values of original image

    //    CGContextFillRect(context, rect);

    //

    //    //Set the original greyscale template as the overlay of the new image

    //    UIImage *imgData = [self verticallyFlipImage:image];

    //    [imgData drawInRect:imageRect];

    //    UIImage *colouredImage = UIGraphicsGetImageFromCurrentImageContext();

    //    UIGraphicsEndImageContext();

    //    CGContextRelease(context);

    //

    //    return colouredImage;

    //方案三,CGBitmapContextCreate方案,内存没释放

    //    CGFloat targetWidth = imageSize.width * [UIScreen mainScreen].scale;

    //    CGFloat targetHeight = imageSize.height * [UIScreen mainScreen].scale;

    //    CGImageRef imageRef = [image CGImage];

    //    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);

    //    CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef);

    //    CGContextRef bitmapContext;

    //    bitmapContext = CGBitmapContextCreate(NULL, targetWidth, targetHeight,CGImageGetBitsPerComponent(imageRef),CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);

    //    CGContextDrawImage(bitmapContext, CGRectMake(0, 0, targetWidth, targetHeight), imageRef);

    //    CGImageRef imgref = CGBitmapContextCreateImage(bitmapContext);

    //    UIImage* newImage = [UIImage imageWithCGImage: imgref];

    //    CGColorSpaceRelease(colorSpaceInfo);

    //    CGContextRelease(bitmapContext);

    //    CGImageRelease(imgref);

    //    return newImage;

    //方案四,CGBitmapContextCreate方案,但是采用CGDataProviderCreateWithCFData方案解决内存占用问题

    //    NSData *data = UIImageJPEGRepresentation(image, 1);

    //    CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);

    //    CGImageRef imageRef = CGImageCreateWithJPEGDataProvider(dataProvider,

    //                                                           NULL, NO,

    //                                                           kCGRenderingIntentDefault);

    //

    //    CGFloat targetWidth = imageSize.width * [UIScreen mainScreen].scale;

    //    CGFloat targetHeight = imageSize.height * [UIScreen mainScreen].scale;

    //    //        CGImageRef imageRef = [image CGImage];

    //

    //    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);

    //

    //    CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef);

    //    CGContextRef bitmapContext;

    //    bitmapContext = CGBitmapContextCreate(NULL, targetWidth, targetHeight,CGImageGetBitsPerComponent(imageRef),0, colorSpaceInfo, bitmapInfo);

    //    CGContextDrawImage(bitmapContext, CGRectMake(0, 0, targetWidth, targetHeight), imageRef);

    //

    //    // If failed, return undecompressed image

    //    if (!bitmapContext) return image;

    //

    //    CGImageRef imgref = CGBitmapContextCreateImage(bitmapContext);

    //    UIImage* newImage = [UIImage imageWithCGImage:imgref];//[UIImage imageWithCGImage:decompressedImageRef scale:image.scale orientation:image.imageOrientation];

    //   

    //    CGColorSpaceRelease(colorSpaceInfo);

    //    CGContextRelease(bitmapContext);

    //    CGImageRelease(imgref);

    //   

    //    return newImage;

}

2      延迟加载

2.1    资源文件的延迟加载

非延迟加载方式

延迟加载方式

2.2    故事板和nib文件的延迟加载

2.2.1  故事板的延迟加载

        Segue定义的两个视图控制器的导航关系,也来维护和管理下一个视图控制器的延迟加载时机,这种情况下我们无法“插手”视图控制器的延迟加载。但是一种情况下除外,就是使用了故事板,而控制器之间没有定义导航关系,没有定义Segue。

2.2.2  nib文件延迟加载

        相当于故事板而言nib要灵活的很多,nib文件有两种:一种是描述视图控制器的,另一种是描述视图的,加载方式有所区别。

3      数据持久化的优化

文件

SQLite数据库

CoreData

3.1    使用文件

l  避免多次写入很少的数据,最好是当数据积攒的一定数量,一次写入。

l  将文件读写访问从主线程中剥离出来,由一个子线程负责。

l  写入应该采用增量方式,每次只写入变化的部分,不要为改变几个字节

l  写入整个文件。

3.1.1  文件结构优化

        文件要保存数据,应该是结构化的,苹果中的plist文件就是很好的结构化文件。plist文件结构是层次模型的树形结构,层次的深浅会影响读取/写入的速度。

3.1.2  文件大小优化

l  + dataWithPropertyList: format: options: error: 按照指定的格式和操作参数,序列化属性列表对象到NSData对象。

l  + propertyListWithData: options: format: error: 按照指定的格式和操作参数,从NSData对象反序列化到属性列表对象中。

3.2    使用SQLite数据库

3.2.1  表结构优化

        在iOS这些CPU处理能力低、内存少、存储空间少情况下,我们不能在本地建立复杂表关系,表的个数也不宜超过5个,表中的字段数量也不宜太多。

        移动设备中的数据是不可能是企业级系统数据的全部,它只是企业级系统的补充和扩展。

3.2.2  查询优化
3.2.2.1 索引

        索引能够提供查询性能,哪些字段需要创建索引很关键,这些字段只有在表连接或where条件子句中使用才能提供查询性能;在INTEGER PRIMARY KEY字段上不用建索引,表中数据很少情况下建索引效果不大。

3.2.2.2 限制返回记录数

        在限制返回记录数方面,由于移动设备屏幕相当比较小,屏幕上能显示的数据不多,一次查询出记录数,超过屏幕显示能显示行数,这就没有必须了,也会占用更多的内存、耗费宝贵的CPU时间。因此我们需要为查询添加返回记录数的限制,下面语句是SQLite支持的写法:

SELECT * FROM Note Limit 10 Offset 5;

3.2.2.3 where条件子句

        尽量不用使用Like模糊匹配查询,如果可能则使用“=”号查询。还有尽量不要使用IN语句,可以使用“=”号和or替。还有多个条件中要把非文本的条件放在前面,文本条件放在后面,如下代码:

(salary > 5000000) AND (lastName LIKE 'Guan') 优于 (lastName LIKE 'Guan')AND (salary > 5000000)

3.2.3  插入(或删除)优化

        关闭数据同步 PRAGMA synchronous = OFF,插入完成也可以设置回来PRAGMA synchronous =NORMAL或PRAGMA synchronous = FULL。

        在Objective-C可以调用函数sqlite3_exec实现设置,语句如下:

sqlite3_open(DATABASE, &db);

sqlite3_exec(db, "PRAGMA synchronous = OFF", NULL, NULL, &err);

3.3    使用CoreData

3.3.1  使用存储类型NSSQLiteStoreType

        CoreData的存储类型有NSSQLiteStoreType、NSBinaryStoreType和NSInMemoryStoreType。其中我们注意采用NSSQLiteStoreType类型,这样底层存储就采用了SQLite数据库,SQLite数据库的优点也能发挥出来。

3.3.2  查询优化

        它的查询是通过NSFetchRequest执行Predicate定义的逻辑查询条件实现的,优化规则上与SQLite的where条件子句是一样的。此外,查询返回记录数的限制,可以使用语句:

NSFetchRequest *request = [[NSFetchRequest alloc] init];

//限制⼀一次提取记录数

[request setFetchLimit:10];

//限制提取记录偏移量

[request setFetchOffset:5];

3.3.3  设置PRAGMA指令
3.3.4  Instruments工具中CoreData跟踪模板

4      可重用对象的使用

l  表视图(UITableView)

l  集合视图(UICollectionView)

l  地图视图(MKMapView)

4.1    表视图中的重用对象

4.1.1  表视图单元格

dequeueReusableCellWithIdentifier:和 dequeueReusableCellWithIdentifier:forIndexPath:

dequeueReusableCellWithIdentifier: 方法通过可以中标识符从表视图中获得可重用单元格,模式代码如下。

4.1.2  表视图节头脚视图

        使用表视图的dequeueReusableHeaderFooterViewWithIdentifier:方法获得UITableViewHeaderFooterView对象,如果没有可重用的UITableViewHeaderFooterView对象,则使用initWithReuseIdentifier:构造方法创建。模式代码如下:

4.2    集合视图中的重用对象

4.2.1  单元格视图
4.2.2  补充视图

4.3    地图视图中的重用对象

4.3.1  MKPinAnnotationView对象

5      并发处理与多核CPU

5.1    主线程阻塞问题

ViewController.m中的click:方法

6      编译器和编译参数

6.1    GCC、LLVM GCC与Apple LLVM比较

l  GCC(GNU Compiler Collection,GNU编译器套装),是一套由 GNU 开发的编程语言编译器。也是LinuxUnix及Mac OS X 操作系统的标准编译器,GCC可以编译C、C++、Objective-C、Java和Pascal等语言。

l  LLVM(Low Level Virtual Machine,低级虚拟机),这个虚拟机提供了一套中立的中间代码和编译基础设施,并围绕这些设施提供了一套全新的编译策略(使得优化能够在编译、连接、运行环境执行过。LLVM GCC是 LLVM下编译C、C++和Objective-C编译器。

l  Apple LLVM,是苹果LLVM编译器,2005年开始称为了苹果官方支持的编译器。2010 WWDC(Worldwide Developers Conference,苹果电脑全球研发者大会),苹果公司报告LLVM编译器比GCC编译器快60%。在Xcode 4之后默认采用Apple LLVM编译器。

6.2    Optimization Level

Optimization Level有5个级别

l  -O0,是默认级别,不进行任何的优化,直接将源代码编译到执行文件中,结果不进行任何的重排,编译时间比较长。主要用于调试程序,可以设置断点、改变变量、计算表达式等调试工作。

l  -O1(或-O),是最常用的优化级别,不考虑速度和文件大小权衡问题,与-O0级别相比生成文件更小,可执行的速度更快,编译时间更少。

l  -O2,是在-O1级别基础上再进行优化,增加的指令调度的优化,与-O1级别相比生成文件大小没有变大,编译时间变长了,编译期间占用内存更多了,但程序的运行速度有所提高。该级别是应用程序发布时候的最理想级别,在增加文件大小的情况下提供了最大优化。

l  -O3,是在-O2和-O1级别上再进行优化,该级别可能会提高程序的运行速度,但是也会增加文件的大小。

l  -Os,该种级别用于在有限的内存和磁盘空间下生成尽可能小的文件,由于使用了很好的缓存技术,在某些情况下也会有很快的运行速度。

7      参考资料

iOS优化(一)内存优化经验

http://www.jianshu.com/p/ef52250df748

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-10-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【IOS开发基础系列】SDWebImageDownloader专题
        SDWebImage是一个很厉害的图片缓存的框架。既ASIHttp+AsyncImage之后,我一直使用AFNetworking集成的UIImageView+AFNetworking.h,但后者对于图片的缓存实际应用的是NSURLCache自带的cache机制。而NSURLCache每次都要把缓存的raw  data 再转化为UIImage,就带来了数据处理和内存方面的更多操作。具体的比较在这里。
江中散人_Jun
2023/10/16
8340
【IOS开发基础系列】SDWebImageDownloader专题
【IOS开发高级系列】异步绘制专题
用CGImageCreateCopy 或者CGImageCreateCopyWithColorSpace函数拷贝
江中散人_Jun
2022/03/08
1.5K0
【IOS开发高级系列】异步绘制专题
分分钟解决iOS开发中App启动广告的功能
allluckly.cn 前不久有朋友需要一个启动广告的功能,我说网上有挺多的,他说,看的不是很理想。想让我写一个,于是乎,抽空写了一个,代码通俗易懂,简单的封装了一下,各种事件用block回调的,有俩种样式的广告,一种是全屏广告,另一种是下面露logo的,类似网页新闻的启动广告。依赖SDWebImage主要用来下载网络的广告图片,一般项目里面网络图片都用的这个框架,所以在此不做过多的阐述。下面让我们来看看我封装的过程,对于新手来说,可以学习一下这种封装的思想。 1.首先建一个继承View的LBLaunch
Bison
2018/07/04
3.4K0
iOS实现毛玻璃效果,图片模糊效果的三种方法
App设计时往往会用到一些模糊效果或者毛玻璃效果,iOS目前已提供一些模糊API可以让我们方便是使用。
用户7705674
2021/10/29
2.7K0
IOS开发系列——异步绘制专题
用CGImageCreateCopy或者CGImageCreateCopyWithColorSpace
江中散人_Jun
2022/03/08
1.5K0
IOS开发系列——异步绘制专题
短视频直播源码,iOS图片去背景
Camera-on-Coffee-Table_1EBVyCTLzJiT.jpeg 短视频直播源码,iOS图片去背景相关的代码 - (UIImage *)removeBackgroudWithImage: (UIImage *)image{     unsigned char *targetData = malloc(sizeof(unsigned char) * image.size.width *image.size.height *4);     UIGraphicsBeginImageContex
yunbaokeji柯基
2020/11/20
6050
短视频直播源码,iOS图片去背景
iOS开发笔记(七)
正文 这次分享三个有意思的问题:二维码生成、Xcode8单元测试的问题、添加新字体。 二维码生成 iOS平台上的二维码生成有很多第三方库,也可以使用原生的方法,这里选用的是QREncoder。 二维码的生成非常简单,仅需几行代码,如下: DataMatrix* qrMatrix = [QREncoder encodeWithECLevel:QR_ECLEVEL_H version:QR_VERSION_AUTO string:urlStr]; int qrcodeImageDimensio
落影
2018/04/27
1.4K0
iOS开发笔记(七)
iOS压缩图片大小
最近碰到一个比较愚蠢的问题,项目中做的拍照或者从相册选择图片上传时,没有经过处理,直接把原图上传了,导致在列表中看的时候,明明是小图片流量却要爆炸了,想想iphone拍出照片大小可都是以M为单位的。所以赶紧做了下压缩处理再上传。为了方便根据不同压缩需求调用,这里采用调用可修改参数的方法的做法,更加灵活一点。调用的方法如下:
Cloudox
2021/11/23
1.4K0
iOS界面黑白实现
a. 针对图片的处理:大部分图片的显示都是最后都是调用UIImageView的setImage方法,所以hook这个方法,在显示前生成灰色的图片,然后在赋值,代码如下:
莫空9081
2022/12/12
1.5K0
iOS_给View的部分区域截图 snapshot for view
这些 api 已被废弃,所以需要判断 iOS 版本 写两套代码: Replace usage of UIGraphicsBeginImageContextWithOptions with UIGraphicsImageRenderer. Replace usage of UIGraphicsGetImageFromCurrentImageContext with UIGraphicsImageRendererContext.currentImage.
mikimo
2023/12/18
8031
iOS_给View的部分区域截图 snapshot for view
iOS 之 异步绘制原理
这其中的工作都是在主线程中完成的,这就导致了主线程频繁的处理 UI 绘制的工作,如果要绘制的元素过多,过于频繁,就会造成卡顿。
网罗开发
2021/04/07
3.4K0
iOS 之 异步绘制原理
ios zxing扫码问题
在ios 中 扫瞄二维码,条形码基本有 2中第三方的库,一个是zbar 一个是zxing,zxing 在android中表现的比较出色,但是在ios 中不是很好用,扫瞄效率低,我们一般都用zbar,但
xiangzhihong
2018/02/05
2.2K0
ios zxing扫码问题
ios通过按钮点击异步加载图片代码
@interface UIButton (AsyncImage) //size by point (void)setImageFromURL:(NSString )urlString adjustToSize:(CGSize)size completion:(void (^)(void))completion logo:(UIImage )logoImage; @end @implementation UIButton (AsyncImage) (void)setImageFromURL:(NSStr
大师级码师
2021/10/29
1.7K0
iOS学习——图片压缩到指定大小以内
  在我们开发过程中,有可能会遇到拍照、或者从相册中选择图片,要么单选或者多选,然后上传图片到服务器,一般情况下一张图片可能3-4M,如果类似微信朋友圈上传9张图片大约是 35M左右,如果我们上传 35M左右的图片到服务器,可想而知后台的压力有多大,最主要的还是特别耗时,如果是在网速比较慢,那么用户上传图片可能需要4-5分钟,那么用户就会受不了,可能会退出应用。所有在开发过程中,考虑到手机性能、网络性能等因素的影响,更重要的是后台服务器的内存、网络等性能的限制,我们再通过网络发送图片等信息时不能发送超过一定大小的图片,如果超过了指定大小,我们需要进行压缩后发送。
mukekeheart
2019/09/29
4.4K0
iOS开发CoreGraphics核心图形框架之七——图像处理
    位图图像数据实际上一个像素阵列,其中每个像素代表了图像中的一个点。位图实际上只支持矩形区域的渲染,但是使用透明技术可以实现任意形状图像的渲染。开发者也可以对要进行渲染的图像进行旋转、切割等操作。
珲少
2018/08/15
1.6K0
iOS开发CoreGraphics核心图形框架之七——图像处理
Core ML简介及实时目标检测及Caffe TensorFlow coremltools模型转换
Core ML简介及实时目标检测,Caffe、Tensorflow与Core ML模型转换、Vision库的使用 转载请注明出处 https://cloud.tencent.com/developer/user/1605429 本篇文章首先会简要介绍iOS 11推出的Core ML机器学习框架,接着会以实际的已经训练好的Caffe、Tensorflow模型为例,讲解coremltools转换工具的使用,以及如何在iOS端运行相关模型。 当今是人工智能元年,随着深度学习的火热,人工智能又一次出现在大众视野中,
WWWWDotPNG
2018/04/10
3.2K0
Core ML简介及实时目标检测及Caffe TensorFlow coremltools模型转换
iOS 图片处理 生成文字图片
工具类 import UIKit ///图片工具类 class ZJImageUtils{ static var textBgColor:[String:UIColor] = [:]; internal static func randomColor()-> UIColor{ var color = ["#E1B154","#D2945B", "#E57257","#38B1A2",
码客说
2019/10/22
6.3K0
iOS TabBar 轮子
今天在GitHub上找了一个TabBar的轮子,Star 6.5k还不错,日常开发已经够用了,设置图片,选中图片,文本颜色,选中文本颜色,数字角标,选中动画,中间凸起按钮都有,日常开发已经够用了。具体可以去GitHub上看文档。 CYLTabBarController 自己写的Demo
赵哥窟
2021/12/16
1.1K0
iOS TabBar 轮子
iOS 中获取某个视图的截图
最近在做SDK的截图,想触发类似系统的截屏功能,找了一圈,总结一下靠谱的几种方式。 我写了个UIView 的category,将这几种方式封装和简化了一下。
Haley_Wong
2018/08/22
3.1K0
iOS复习中有关SDWebImage可能知识点总结(2)
分为内存缓存(利用SDImageCache类的NSCache属性),磁盘缓存(利用NSFileManager),和操作缓存(利用runtime关联的字典属性)。下载之前先查询缓存,没有就下载并在下载后保存图片到缓存。
陈满iOS
2018/09/10
8580
iOS复习中有关SDWebImage可能知识点总结(2)
相关推荐
【IOS开发基础系列】SDWebImageDownloader专题
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档