美文网首页
AFNetworking 2.x 阅读笔记(五)

AFNetworking 2.x 阅读笔记(五)

作者: brownfeng | 来源:发表于2016-08-16 11:16 被阅读45次

    HTTP 请求Request参数设置, 请求的具体过程都已经执行完成,本篇来总结 responseSerialization.

    总的结构

    整个 response 解析的部分主要包括:

    • protocol AFURLResponseSerialization
    • 基类 AFHTTPResponseSerializer
    • 多个子类:
      AFJSONResponseSerializer;,AFXMLParserResponseSerializer,AFXMLDocumentResponseSerializer,AFPropertyListResponseSerializer,AFImageResponseSerializer, AFCompoundResponseSerializer

    它们具体的关系图如下:

    requestResponse.png

    从关系图中可以看出他们之间的关系.AFURLResponseSerialization protocol 的方法主要将 response data 转化成一个 id 类型的数据, 这里具体转化成何种数据, 需要自己去定义 ,比如 AFNetworking 框架中已经给出几个: JSON对象, XML 对象, Image等等. AFHTTPResponseSerializer基类实现了AFURLResponseSerialization protocol 方法,并且实现解析数据之前的一个基本需求: 验证 response 对象的合法性, 包括 response status code 和 content type.

    /**
     The response object decoded from the data associated with a specified response.
    
     @param response The response to be processed.
     @param data The response data to be decoded.
     @param error The error that occurred while attempting to decode the response data.
    
     @return The object decoded from the specified response data.
     */
    - (nullable id)responseObjectForResponse:(nullable NSURLResponse *)response
                               data:(nullable NSData *)data
                              error:(NSError * __nullable __autoreleasing *)error
    
    
    /**
     Validates the specified response and data.
    
     In its base implementation, this method checks for an acceptable status code and 
    content type. Subclasses may wish to add other domain-specific checks.
    
     @param response The response to be validated.
     @param data The data associated with the response.
     @param error The error that occurred while attempting to validate the response.
    
     @return `YES` if the response is valid, otherwise `NO`.
     */
    - (BOOL)validateResponse:(nullable NSHTTPURLResponse *)response
                        data:(nullable NSData *)data
                       error:(NSError * __nullable __autoreleasing *)error;
    

    JSONResposneSerializer 将 json -> object

    选取一个代表性的子类AFJSONResponseSerializer

    在初始化对象时候,声明接受的 ContentType 的类型只有@"application/json", @"text/json", @"text/javascript",如果服务器的 response 中 ContentType 是"text/html",需要在这里添加.最好的方式是自己实现一个 AFXXXXResponseSerializer.

    self.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", nil];
    

    在实现responseObjectForResponse:data:error方法中, 使用系统的NSJSONSerialization解析json,代码中具体的数据格式变化: NSData->NSString->NSData->NSObject(主要是因为系统解析 json 的函数只支持 UTF-8格式).如果和服务器约定好使用 UTF-8格式传递数据, 这里可以省略前两步的转换(自己继承AFHTTPResponseSerializer, 自己实现一个 responseSerializer)。最后实现了方法删除了 json 中的 nil 值.

    图片处理

    bangs blog 中提到, 加载网络图片中可能出现的问题:
    当我们调用UIImage的方法imageWithData:方法把数据转成UIImage对象后,其实这时UIImage对象还没准备好需要渲染到屏幕的数据,现在的网络图像PNG和JPG都是压缩格式,需要把它们解压转成bitmap后才能渲染到屏幕上,如果不做任何处理,当你把UIImage赋给UIImageView,在渲染之前底层会判断到UIImage对象未解压,没有bitmap数据,这时会在主线程对图片进行解压操作,再渲染到屏幕上。这个解压操作是比较耗时的,如果任由它在主线程做,可能会导致速度慢UI卡顿的问题。
    AFImageResponseSerializer除了把返回数据解析成UIImage外,还会把图像数据解压,这个处理是在子线程(AFNetworking专用的一条线程,详见AFURLConnectionOperation),处理后上层使用返回的UIImage在主线程渲染时就不需要做解压这步操作,主线程减轻了负担,减少了UI卡顿问题。
    具体实现上在AFInflatedImageFromResponseWithDataAtScale里,创建一个画布,把UIImage画在画布上,再把这个画布保存成UIImage返回给上层。只有JPG和PNG才会尝试去做解压操作,期间如果解压失败,或者遇到CMKY颜色格式的jpg,或者图像太大(解压后的bitmap太占内存,一个像素3-4字节,搞不好内存就爆掉了),就直接返回未解压的图像。

    这里可以参考 SDWebImage 的源码分析.

    相关文章

      网友评论

          本文标题:AFNetworking 2.x 阅读笔记(五)

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