iOS开源项目学习—— AFNetworking

网络上已有对AFNetworking的很好的分析,如:

对于AFNetworking的详细介绍,可以参考作者Mattt Thompson的在AFNetworking 2.0的介绍。

NSURLConnection

  • AFURLConnectionOperation继承自NSOperation,并实现了NSURLConnection的代理方法。它是所有网络请求操作的基类。
  • AFHTTPRequestOperation继承自AFURLConnectionOperation,使用HTTP或者HTTPS来进行请求。它封装了acceptable status codes 和content types的类型,这是用来确定一个请求失败或成功的。
  • AFHTTPRequestOperationManager封装了web应用通过HTTP请求的通用模式,包括请求的创建、响应的序列化,网络状态的监控和安全,以及网络请求的管理。
AFURLConnectionOperation
NSRecursiveLock

AFURLConnectionOperation在很多地方都使用到了递归锁。例如:

//字符串编码格式
- (NSStringEncoding)responseStringEncoding {
    [self.lock lock];
    if (!_responseStringEncoding && self.response) {
        NSStringEncoding stringEncoding = NSUTF8StringEncoding;
        if (self.response.textEncodingName) {
            CFStringEncoding IANAEncoding = CFStringConvertIANACharSetNameToEncoding((__bridge CFStringRef)self.response.textEncodingName);
            if (IANAEncoding != kCFStringEncodingInvalidId) {
                stringEncoding = CFStringConvertEncodingToNSStringEncoding(IANAEncoding);
            }
        }

        self.responseStringEncoding = stringEncoding;
    }
    [self.lock unlock];

    return _responseStringEncoding;
}

NSRecursiveLock这种“递归锁”,线程能够多次持有该锁,而不会出现“死锁”现象。
OC中,还有其它形式的锁,参考内容来自:

NSURLConnection与NSRunLoop

在- (void)operationDidStart 方法中,有如下形式的代码:

    self.connection = [[NSURLConnection alloc] initWithRequest:self.request delegate:self startImmediately:NO];

    NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
    for (NSString *runLoopMode in self.runLoopModes) {
        [self.connection scheduleInRunLoop:runLoop forMode:runLoopMode];
        [self.outputStream scheduleInRunLoop:runLoop forMode:runLoopMode];
    }

self.runLoopModes为:

self.runLoopModes = [NSSet setWithObject:NSRunLoopCommonModes];

至于为什么NSURLConnection要与NSRunLoop结合起来使用,请参考一个异步网络请求的坑:关于NSURLConnection和NSRunLoopCommonModes

首先,如果是直接调用NSURLConnection的initWithRequest:delegate:startImmediately:(第三个参数用YES,这个是designated
initializer)或者方法initWithRequest:delegate:时,NSURLConnection会默认运行在NSDefaultRunLoopMode模式下,即使再使用scheduleInRunLoop:forMode:设置运行模式也没有用。如果NSURLConnection运行在NSDefaultRunLoopMode下,何为Run
Loop的模式Mode,请参考这篇Blog), 这篇Blog提到NSDefaultRunLoopMode是Run
Loop默认的运行模式,用于处理除了NSConnection对象的事件。
然而如果NSURLConnection是运行在NSDefaultRunLoopMode,而当前线程是主线程,并且UI上有类似滚动这样的操作,那么主线程的Run
Loop会运行在UITrackingRunLoopMode下,就无法响应NSURLConnnection的回调。此时需要首先使用initWithRequest:delegate:startImmediately:(第三个参数为NO)生成NSURLConnection,再重新设置NSURLConnection的运行模式为NSRunLoopCommonModes,那么UI操作和回调的执行都将是非阻塞的,因为NSRunLoopCommonModes是一组run
loop mode的集合,默认情况下包含了NSDefaultRunLoopMode和UITrackingRunLoopMode。

AFHTTPRequestSerializer

AFHTTPRequestSerializer主要用来创建格式化请求参数,生成HTTP Header。
在其+ (instancetype)serializer类方法中,会设置Accept-Language、User-Agent等:
设置Accept-Language

NSMutableArray *acceptLanguagesComponents = [NSMutableArray array];
[[NSLocale preferredLanguages] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    float q = 1.0f - (idx * 0.1f);
    [acceptLanguagesComponents addObject:[NSString stringWithFormat:@"%@;q=%0.1g", obj, q]];
    *stop = q <= 0.5f;
}];
[self setValue:[acceptLanguagesComponents componentsJoinedByString:@", "] forHTTPHeaderField:@"Accept-Language"];

 Accept-Language: zh-cn,zh;q=0.5   
意思:浏览器支持的语言分别是中文和简体中文,优先支持简体中文。
详解:Accept-Language表示浏览器所支持的语言类型;   
zh-cn表示简体中文;zh 表示中文;
  q是权重系数,范围 0 =< q <= 1,q 值越大,请求越倾向于获得其“;”之前的类型表示的内容,若没有指定 q
值,则默认为1,若被赋值为0,则用于提醒服务器哪些是浏览器不接受的内容类型。

设置User-Agent
User-Agent是Http协议中的一部分,属于头域的组成部分,User Agent也简称UA。用较为普通的一点来说,是一种向访问网站提供你所使用的浏览器类型、操作系统及版本、CPU 类型、浏览器渲染引擎、浏览器语言、浏览器插件等信息的标识。UA字符串在每次浏览器 HTTP 请求时发送到服务器!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值