iOS开源项目学习—— AFNetworking
发布日期:2022-03-18 08:27:35 浏览次数:50 分类:技术文章

本文共 3478 字,大约阅读时间需要 11 分钟。

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

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

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的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 请求时发送到服务器!

转载地址:https://windzen.blog.csdn.net/article/details/48711473 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:iOS UICollectionView: The Complete Guide摘要
下一篇:CGPath使用

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2024年04月15日 21时59分38秒