美文网首页
2019-12-15写点笔记...不成文.到时候再整理成文章

2019-12-15写点笔记...不成文.到时候再整理成文章

作者: YBDSup | 来源:发表于2019-12-15 23:18 被阅读0次
    1. DB的block如果捕获到比较大的数据量(假设是数组A),且DB的block这样的操作比较繁密的情况底下,会造成block的堆积,进而造成block捕获到的数组A的内存堆积,最终有可能会导致内存涨到被系统杀掉。

    实际上是通式:会被延迟执行的block中捕获的数据量不小(_a),且有可能这个操作后面会频繁调用(_b)的话会导致内存的堆积。
    所以我们要么:不让他捕获那么大的数据量,改成单例(_a处下手),要么不要频繁调用这样的延迟带block的操作(_b处下手)。

    1. Swift的设计模式书中第4章提到,对象模版模式。暂时的理解,思想类似于工厂模式。作者举的例子是:

    用swift的元组作为数据结构进行存储,修改,然后在传参的时候直接传一整个元组过去的时候,当数据结构发生修改,其对应的接口,都要进行相应的修改。

    // 假设对应表示着:名字,数量,价格
    //[(String,Int,Double)] 改成[String,Double]//假设这个数据结构我们这里称他为组件b
    
    func oldFunc1(sth:(String,Int,Double))->String {
        return sth.0 + "\(1 + sth.2 * sth.2)";
    }
    func oldFunc1_ver2(sth:(String,Double))->String {// 发生改变
        return sth.0 + "\(1 + sth.1 * sth.1)";// 发生改变
    }
    

    上面这个例子中的oldFun1(组件a)就紧耦合于组件b(这个元组),b发生任何改变,oldFun1等一系列和组件b有紧耦合的部分都要修改。
    后续给出的作为对象模版模式的例子是将这个元组,封装成对象。

    func oldFunc1_verCorrect(data:SomeData)->String {
        return data.name + "\(1 + data.price * data.price)";
    }
    
    
    1. 另外描述下之前比较纠结的一个点:请求B是最终获取数据进行展示的请求(会带有参数b,有默认值:$$$,但有可能会是上次请求的值),请求A是用于校验参数b本身正确与否的,如果不正常,应当用b默认参数$$$发起一个新的请求B(B2)。当时想到的解决方案是:同时发起AB,存在的问题是:B2和一开始的B1有可能有覆盖的问题,所以就用了标志位来解决这个问题,写得代码写得有点复杂。想到的最完美的是,服务端做b的校验,在返回的结果中,带上正确的b。

    // 要在跟随列表reloadData之后才能更新layout.不然layout使用的为缓存的值

    *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UICollectionView received layout attributes for a cell with an index path that does not exist: <NSIndexPath: 0xabc64847c85f5fd9> {length = 2, path = 0 - 0}'

    1. 没懂..UIViewContentModeScaleAspectFill和另外自己做离屏渲染裁剪好的照片再来设置,两者效率,之类有什么差别吗?((按照引用部分的解释,一个是在解码的时候占了资源,另外一个是生成中间位图bitmap大量内存)以下引用涵盖一个大图片的内存优化的指引)

    图片内存使用优化
    1.使用适当尺寸的图片
    我们知道,解压后的图片是由一个个像素点组成的。每个像素点一般有R、G、B、A(红绿蓝透明度)四个通道,每个通道是8位,因此一个像素通常占用4字节。对于一张图片,如果同样是300*300分辨率的jpeg和png两张图,文件大小可能差几倍,但是渲染后的内存开销是完全一样的。
    而由于机型的不同,下载的图片经常与最终展示在界面上的尺寸不同。如果我们将一张矩形图片展示在很小的view里,原图解压会消耗大量内存,但最终大部分像素最终都被丢掉浪费了。或者将图片手动缩放成合适大小,处理过程中仍然可能会多占用一部分内存。

    因此,我们与服务端共同制定了一套方案,在服务端将图片裁剪成控件的精确尺寸(记得乘上屏幕缩放比例[UIScreen mainScreen].scale)下发到不同机型,从根本上将内存使用降低。

    出自《你真的了解OOM吗?——京东iOS APP内存优化实录》

    但是,文章中同时也指出,图片的缩放方案采用ImageIO的写法能比普通的缩放写法更节省内存

    3.注意图片缩放方式
    参考Apple的 WWDC18 Session 416 —— iOS Memory Deep Dive,处理图片缩放时,直接使用UIImage会在解码时读取文件占用一部分内存,还会生成中间位图bitmap消耗大量内存,而ImageIO不存在上述两种内存消耗,只会占用最终图片大小的内存。(此处可以参考Linux的mmap内存映射)

    /// 常见的UIimage缩放写法: 
    - (UIImage *)scaleImage:(UIImage *)image newSize:(CGSize)newSize{
        UIGraphicsBeginImageContextWithOptions(newSize, NO, 0);
        [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
         
        return newImage;
    }
    
    /// 节约内存的ImageIO缩放写法:
    + (UIImage *)scaledImageWithData:(NSData *)data withSize:(CGSize)size scale:(CGFloat)scale orientation:(UIImageOrientation)orientation{
        CGFloat maxPixelSize = MAX(size.width, size.height);
        CGImageSourceRef sourceRef = CGImageSourceCreateWithData((__bridge CFDataRef)data, nil);
        NSDictionary *options = @{(__bridge id)kCGImageSourceCreateThumbnailFromImageAlways : (__bridge id)kCFBooleanTrue,
                                  (__bridge id)kCGImageSourceThumbnailMaxPixelSize : [NSNumber numberWithFloat:maxPixelSize]};
        CGImageRef imageRef = CGImageSourceCreateThumbnailAtIndex(sourceRef, 0, (__bridge CFDictionaryRef)options);
        UIImage *resultImage = [UIImage imageWithCGImage:imageRef scale:scale orientation:orientation];
        CGImageRelease(imageRef);
        CFRelease(sourceRef);
     
        return resultImage; 
    }
    

    同样出自《你真的了解OOM吗?——京东iOS APP内存优化实录》

    相关文章

      网友评论

          本文标题:2019-12-15写点笔记...不成文.到时候再整理成文章

          本文链接:https://www.haomeiwen.com/subject/hnalnctx.html