• iOS 优化内存的方法


    1.把views设置为透明,透明的Views你应该设置它们的opaque属性为YES。

    原因是这会使系统用一个最优的方式渲染这些views。这个简单的属性在IB或者代码里都可以设定。

    Apple的文档对于为图片设置透明属性的描述是:

    (opaque)这个属性给渲染系统提供了一个如何处理这个view的提示。如果设为YES,渲染系统就认为这个view是完全不透明的,这使得渲染系统优化一些渲染过程和提高性能。如果设置为NO,渲染系统正常地和其它内容组成这个View。默认值是YES。

    在相对比较静止的画面中,设置这个属性不会有太大影响。然而当这个view嵌在scroll view里边,或者是一个复杂动画的一部分,不设置这个属性的话会在很大程度上影响app的性能。

    你可以在模拟器中用DebugColor Blended Layers选项来发现哪些view没有被设置为opaque。目标就是,能设为opaque的就全设为opaque!

    2.对于仅使用一次或是使用频率很低的大图片资源不要使用UIImage(named: "")而使用UIImage(contentsOfFile: "")

    UIImage(named: "")返回的对象会保存在缓存中,只有退出程序才会释放内存;但下一次调用快,UIImage(contentsOfFile: "")返回的对象不会保存在缓存中,一旦对象销毁就会释放内存

    3.一些图片本身非常适合用9片图的机制进行拉伸,但没有进行相应的优化

    图片的内存占用是很大的,对于适合用9片图机制进行拉伸处理的图片,可以切出一个比实际尺寸小的多的图片,从而大量减少内存占用。我们可以利用Xcode的slicing功能,设定图片哪些部分不进行拉伸,哪些部分进行拉伸。在加载图片的时候,还是以正常的方式进行加载。

    4.基于颜色创建纯色的图片时,尺寸过大

    有时,我们需要基于颜色创建出UIImage,并用做UIButton在不同状态下的背景图片。由于是纯色的图片,那么,我们完全没有必要创建出和视图大小一样的图像,只需要创建出宽和高均为1px大小的图像就够了
    5.在自定义的UIView子类中,利用drawRect:方法进行绘制改为CAShapeLayer

    自定义drawRect会使APP消耗大量的内存,视图越大,消耗的越多。其消耗内存的计算公式为:
    消耗内存 = (width * scale * height * scale * 4 / 1024 / 1024)MB

    大部分情况下,绘制需求都可以通过CAShapeLayer实现,CAShapeLayer属于CoreAnimation框架,通过GPU来渲染图形,节省性能。动画渲染直接提交给手机GPU,不消耗内存

    渲染快速。CAShapeLayer使用了硬件加速,绘制同一图形会比用Core Graphics快很多。

    高效使用内存。一个CAShapeLayer不需要像普通CALayer一样创建一个寄宿图形,所以无论有多大,都不会占用太多的内存。

    不会被图层边界剪裁掉。

    不会出现像素化。

    6.在Image Views中调整图片大小

    如果要在`UIImageView`中显示一个来自bundle的图片,你尽量保证图片的大小和UIImageView的大小相同。在运行中缩放图片是很耗费资源的,特别是`UIImageView`嵌套在`UIScrollView`中的情况下。

    如果图片是从远端服务加载的你不能控制图片大小,比如在下载前调整到合适大小的话,你可以在下载完成后,最好是用background thread,缩放一次,然后在UIImageView中使用缩放后的图片。

    7.UILabel尺寸过大,为UILable设置背景色
    如果一个UILabel的尺寸,大于ContentSize,那么会引起不必要的内存消耗。所以,在视图布局的时候,我们应该尽量使UILabel的尺寸等于其ContentSize
    如果设置的背景色不是clearColor, whiteColor,会引起内存开销。可以将视图结构转变为UIView+UILabel,为UIView设定背景色,而UILabel只是用来显示文字,这样可以减少内存开销
    8.高清大图片的处理,
    网络下载高清大图片时,禁止解压
    9.第三方库的缓存机制,适时缓存,适时清除
    (1)Lottie动画框架
    Lottie框架默认会缓存动画帧等信息,如果一个应用中使用动画的场合很多,那么随着时间的积累,就会存在大量的缓存信息。然而,有些缓存信息可能以后再也不会被用到了,例如闪屏页的动画引起的缓存。针对Lottie的缓存引起的内存占用,可以根据自己的意愿,选择如下两种处理办法:
        1.禁止缓存 LRUAnimationCache.sharedCache.cacheSize = 0 缓存个数设置为零直接不缓存
        2.适当的地方清除缓存 LRUAnimationCache.sharedCache.clearCache()
    (2)图像缓存框架,如
    SDWebImage的缓存机制,分为Disk和Memory两层,Memory这一层使得图片在被访问时可以免去文件IO过程,提高性能。默认情况下,Memory里存储的是解压后的图像数据,这个会导致巨大的内存开销。如果想要优化内存占用,可以选择存储压缩的图像数据,在应用启动的地方加如下代码
    [SDImageCache sharedImageCache].config.shouldDecompressImages = NO;
    [SDWebImageDownloader sharedDownloader].shouldDecompressImages = NO;
    10.重用和延迟加载(lazy load) Views

    更多的view意味着更多的渲染,也就是更多的CPU和内存消耗,对于那种嵌套了很多view在UIScrollView里边的app更是如此。

    这里我们用到的技巧就是模仿`UITableView`和`UICollectionView`的操作:不要一次创建所有的subview,而是当需要时才创建,当它们完成了使命,把他们放进一个可重用的队列中。

    这样的话你就只需要在滚动发生时创建你的views,避免了不划算的内存分配。

    创建views的能效问题也适用于你app的其它方面。想象一下一个用户点击一个按钮的时候需要呈现一个view的场景。有两种实现方法:

    1. 创建并隐藏这个view当这个screen加载的时候,当需要时显示它;

    2. 当需要时才创建并展示。

    每个方案都有其优缺点。用第一种方案的话因为你需要一开始就创建一个view并保持它直到不再使用,这就会更加消耗内存。然而这也会使你的app操作更敏感因为当用户点击按钮的时候它只需要改变一下这个view的可见性。

    第二种方案则相反-消耗更少内存,但是会在点击按钮的时候比第一种稍显卡顿。





  • 相关阅读:
    java 如何判断邮箱是否正确
    Android SDK Manager无法更新的解决
    洛谷P1162
    真 随笔
    初始化结构体
    Linux mkdir -p 后出现permission denied问题
    校赛F
    HDU1022
    UVa156
    HDU1060
  • 原文地址:https://www.cnblogs.com/duzhaoquan/p/13661878.html
Copyright © 2020-2023  润新知