美文网首页底层iOS相关
iOS 第三方库的原理解析

iOS 第三方库的原理解析

作者: lukyy | 来源:发表于2021-11-27 13:21 被阅读0次

    前言:GitHub我们常用的第三方框架(开源库)

    其他引用:
    swift常用第三方库
    swift主流 JSON 解析框架

    以下是对开源库原理的简单总结

    1、AFNetworking原理解析

    AFNetworking-3.0 之前,主要是对NSURLConnection进行了封装(iOS9.0废弃),包含以下核心的类:
    AFURLConnectionOperation
    AFHTTPRequestOperationManager
    AFHTTPRequestOperation
    (NSURLConnection 缺点:
    1、 在主线程运行,容易造成线程阻塞
    2、没有下载进度
    3、内存偏高,有一个最大的峰值
    原因:默认Connection是在主线程工作,指定了代理的工作队列之后,整个下载仍然是在主线程,UI事件能够卡主下载
    解决方案:要放在队列中执行NSOperationQueue「开启子线程」,子线程放在Runloop中,并要手动开启Runloop,用完后子线程才能回收
    不能使用:[[NSRunLoop currentRunLoop] run];
    手动使用:CFRunLoopRun();
    AFNetworking 3.0 之后 使用 NSURLSession 进行封装。

    AFNetworking框架由以下五部分组成:

    • NSURLSession:AFURLSessionManagerAFHTTPSessionManager
    • 序列化/反序列化:
      AFURLRequestSerialization上传的数据转换成JSON格式,
      AFJSONResponseSerializer JSON解析器
    • 安全协议:AFSecurityPolicy 是针对 HTTPS的 服务
    • 网络管理器:AFNetworkReachabilityManager
    • UIKit:提供了网络请求过程中与UI界面显示相关的操作接口
      ActivityIndicator、UIAlertView、UIButton、UIImageView、UIprogressView、UIWebView

    NSURLSessionTask为分为三种类型:
    普通任务:NSURLSessionDataTask
    下载任务:NSURLSessionDownLoadTask
    上传任务:NSURLSessionUploadTask

    注意重点:

    • 所有Task的默认状态都是暂停的,需要用[Task resume]启动。
    • NSURLSession对象对其delegate都是强引用的,只有当Session对象invalidate, 才会释放delegate,否则会出现memory leak。

    请求过程

    1、初始化会话管理类:AFURLSessionManager。
    2、配置会话模式类型:NSURLSessionConfig
    3、创建任务Task对象,启动任务
    4、通过KVO监听download进度和upload进度
    5、由任务代理回调处理:AFURLSessionmanagerTaskDelegate,数据响应,错误响应
    //-------------------------------------------------------------------------------------------


    2、SDWebImage原理解析

    1、入口 setImageWithURL:placeholderImage:options:会先把 placeholderImage显示,然后 SDWebImageManager根据 URL 开始处理图片。(以URL的MD5值作为key)

    2、进入SDImageCache从内存缓存查找SDImageCacheDelegate回调给SDWebImageManager,然后通过NSDWebImageManagerDelegate回调展示

    3、如果内存缓存中没有,生成 `NSOperation`添加到队列,开始从硬盘(Disk)查找图片是否已经下载
    有: 回主线程进行结果回调 NotifyDelegate,将图片添加到内存缓存中SDImageCache,再回调展示
    无: 共享或重新生成一个SDWebImageDownloader下载图片,由 NSURLSession实现相关 delegate,来判断图片下载中、下载完成和下载失败。

    下载完后,放入硬盘,加入缓存,再回调展示
    //-------------------------------------------------------------------------------------------


    3、MJExtension原理解析

    框架内的基本函数
    #pragma mark  模型 -> 字典
    - (NSMutableDictionary *)mj_keyValues
    #pragma mark  字典 -> 模型
    + (instancetype)mj_objectWithKeyValues:(id)keyValues;
    #pragma mark  字典数组 -> 模型数组
    + (NSMutableArray *)mj_objectArrayWithKeyValuesArray:(NSArray *)keyValuesArray
    
    #pragma mark 核心代码:
    - (instancetype)mj_setKeyValues:(id)keyValues context:(NSManagedObjectContext *)context
    
    转化过程

    1、NSString、NSData 转化成JSON对象:(NSDictionary本身就是json对象)
    [keyValuesArray mj_JSONObject]
    2、遍历属性,返回属性列表,映射成对象MJProperty。
    在Block回调中可以获取到每一个MJProperty(封装的属性)
    通过单例做属性缓存

    • 检测是否被忽略
    • 取出属性值
    • 值的过滤(提供了尾部可以对特殊值做处理的功能)
    • 类型的转化处理
      NSArray->NSMutableArray,
      NSData->NSMutableData,
      NSDictionary->NSMutableDictionary
      URL类型的字符串:NSString转换为NSURL
      NSNumber -> NSString
      BOOL等类型的转换

    - (instancetype)mj_setKeyValues:(id)keyValues context:(NSManagedObjectContext *)contex

    扩展:
    判断是否为JSON对象
    BOOL isYes = [NSJSONSerialization isValidJSONObject:dict];

    //-------------------------------------------------------------------------------------------


    4、Masonry原理解析

    Masonry常用函数
    #pragma mark  <基础API>
    mas_makeConstraints()    添加约束
    mas_remakeConstraints()  移除之前的约束,重新添加新的约束
    mas_updateConstraints()  更新约束,写哪条更新哪条,其他约束不变
    
    equalTo()       参数是对象类型,一般是视图对象或者mas_width这样的坐标系对象
    mas_equalTo()   和上面功能相同,参数可以传递基础数据类型对象,可以理解为比上面的API更强大
    width()         用来表示宽度,例如代表view的宽度
    mas_width()     用来获取宽度的值。和上面的区别在于:
                    一个代表某个坐标系对象,一个用来获取坐标系对象的值
    
    make.width.lessThanOrEqualTo(@200);      // 设置宽度小于等于200
    make.height.greaterThanOrEqualTo(@(10)); // 设置高度大于等于10
    make.width.equalTo(self.view).multipliedBy(0.2); //设置约束比例
    当前View的宽度是self.view宽度的0.2倍
    
    #pragma mark  <设置约束优先级>
    提供了三个默认的方法,这三个方法内部对应着不同的默认优先级。
    除了这三个方法,我们也可以自己设置优先级的值,可以通过priority()方法来设置。
    priorityLow()、
    priorityMedium()、
    priorityHigh(),
    
    #pragma mark  <更新约束和布局>
    - (void)updateConstraintsIfNeeded  调用此方法,如果有标记为需要重新布局的约束,则立即进行重新布局,内部会调用updateConstraints方法
    - (void)updateConstraints          重写此方法,内部实现自定义布局过程
    - (BOOL)needsUpdateConstraints     当前是否需要重新布局,内部会判断当前有没有被标记的约束
    - (void)setNeedsUpdateConstraints  标记需要进行重新布局
    

    1.没有添加view,就使用了masonry布局。为什么会崩溃?
    解答:调用函数时 closestCommonSuperview不能为空,作者用NSAssert方式让使用者更好调试。

    未完待续。。。

    引用参考:
    iOS进阶_NSURLConnection被弃用的原因

    相关文章

      网友评论

        本文标题:iOS 第三方库的原理解析

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