如何解析AFNetworking框架的解读

68次阅读
没有评论

共计 10155 个字符,预计需要花费 26 分钟才能阅读完成。

今天给大家介绍一下如何解析 AFNetworking 框架的解读。文章的内容丸趣 TV 小编觉得不错,现在给大家分享一下,觉得有需要的朋友可以了解一下,希望对大家有所帮助,下面跟着丸趣 TV 小编的思路一起来阅读吧。

做 ios 开发,AFNetworking 这个网络框架肯定都非常熟悉,也许我们平时只使用了它的部分功能,而且我们对它的实现原理并不是很清楚,就好像总是有一团迷雾在眼前一样。

接下来我们就非常详细的来读一读这个框架的代码,我们的目标就是理解了它的思想之后,能够明白我们的请求是如何实现的,我们的代码哪里还需要进行改进,如果能够更进一步,我们能够总结出一套适合大部分应用的网络架构思想。

能够让一些人从中受益。

我们先来看看整个框架的文件系统,我们先不对每个文件的作用进行说明,在整个源码解读最后的一篇中我们会对整个框架进行总结。会有一张清晰的图表来说明这个问题。

我们在看一个框架的时候呢,可以这样先看,先看每个文件的头文件,也就是.h 文件

可以看到,有的头文件是包含了别的头文件的,在不考虑系统的头文件的情况下,我们能够发现一些比较独立的类,从上图中,我们可以看出

比较独立的类有:

1.AFURLResponseSerialization.h

2.AFNetworkReachabilityManager.h

3.AFURLRequestSerialization.h

4.AFSecurityPolicy.h

下面就介绍 AFNetworkReachabilityManager.h 的内容,这个是用来监控网络环境变化的类。

#import  SystemConfiguration/SystemConfiguration.h

通过导入了这个头文件,我们得知:网络监控的实现是依赖 SystemConfiguration 这个 api 的。说明这个 api 能够提供这样的功能,至少让我们明白了我们平时都会导入它的一个用途。

这是一个枚举封装,还是遵循一个使用枚举的原则,当满足一个有限的并具有统一主题的集合的时候,我们就考虑枚举。在这里作者是枚举了 4 种类型。这几种类型能够满足我们开发中大部分的功能,如果不满足,可以自行进行扩展。

NS_ASSUME_NONNULL_BEGIN
NS_ASSUME_NONNULL_END

这个是为了 swift 的可选类型配添加的,在这两个终点的内容的参数默认都是 nonnull 的。

这段文字是对这个类的说明。我们估且不去管它说了什么,在看看苹果官方的

这样的内容会出现在一个属性或者方法的上方,目的是对其内容的解释。我看到这里就想到了我们平时的开发,我们能够把每段代码都当成是 api 的开发,也把注
释写的详细一点。曾经看过两种不同的说辞,一种是说把代码注释尽量少些,要求代码简介可读性强。另一种是说注释要详细,着重考虑他人读代码的感受。个人感
觉还是写详细一点比较好,因为可能过一段时间之后,自己再去看自己当时写的代码可能就不记得了。很有可能在写这些繁琐的注释的过程中,能够想到些什么,比
如如何合并掉一些没必要的方法等等。

本类提供了四个只读的属性来让我们获取我们需要的内容

1. 网络状态

2. 是否是可达的

3. 当前连接是否是 WWAN

4. 当前连接是够是 WiFi

四个属性均为只读属性,只给了用户访问权,注意 BOOL 属性一般是要写 getter 方法的。

作者使用了这个来分隔同一类中不同功能模块。这个算是个人习惯问题吧。举个平时开发的例子,在.m 文件中我个人使用 #pragma mark 分隔不同功能。

提供了 5 中初始化方法,能够满足大部分的需求。

SCNetworkReachabilityRef 这个很重要,这个类的就是基于它开发的。

+ (instancetype)managerForDomain:(NSString *)domain; 监听制定 domain 的网络状态。

+ (instancetype)managerForAddress:(const void *)address; 监听某个 socket 地址的网络状态,socket 通信请看这篇文章:socket 通信

打开和关闭监听的方法。

返回一个网络状态的本地语言的字符串。往往我们可以根据这个字符串来告诉用户,当前网络发生了什么,当然,也可以根据状态自定义提示文字。

设置网络转态改变的回调,监听网络改变的回调有两种方式:

1. 使用上边的这个方法。

2. 监听 AFNetworkingReachabilityDidChangeNotification 通知。

这个是与网络状态变化相关的通知。接受的通知中会有一个 userinfo 是一个 NSDictionary 其中 key 就是

AFNetworkingReachabilityNotificationStatusItem 

这简单的两行代码能够告诉我们的是,我们平时的开发中 但凡设计到发通知的功能,我们应该把通知的字符串封装到一个专有的文件中,同时在文件内部按不同模块进行区分,当然必要的注释也很有必要。

ps: FOUNDATION_EXPORT 和 #define 都能定义常量。FOUNDATION_EXPORT 能够使用 == 进行判断,效率略高。而且能够隐藏定义细节 (就是实现部分不在. 中)

对函数:根据状态获取字符串   声明。

好了,这个类的.h 文件我们已经非常相信的进行解读了,我们并不是大概的说了下他提供的功能,而是通过读每行代码,我们能联想到什么,什么东西能帮助我们更好的编程。

我们接着看  AFNetworkReachabilityManager.m 的内容

如何解析 AFNetworking 框架的解读

这几个头文件是系统库,是为了后边的  sockaddr_in6 / sockaddr_in 准备的,不熟悉的可以看这篇文章  socket 通信

如何解析 AFNetworking 框架的解读

这几个就没什么好说的了,我们接着看

如何解析 AFNetworking 框架的解读

这个方法是对.h 中最后一个方法的实现。指的我们注意的是 NSLocalizedStringFromTable 这个宏。为什么要注意它呢?

这就涉及到本地国际化的问题。所谓的国际化就是让你的 app 能够根据不同的语言显示相对应的语言。

*** 但这并不简单,没有经验的开发人员,一开始可能不会做这样的设置,如果日后需要国际话了,在做就很麻烦了。所以说在开中,但凡使用到字符串的地方都要考虑语言的不同。不同的语言下,一个意思的表达所使用的字符串长度是不一样的,这就影射出空间的宽度可能会不一样。

好了,国际化的内容就不说了,请自行搜索。

 1 /** 2 *  根据 SCNetworkReachabilityFlags 这个网络标记来转换成我们在开发中经常使用的网络状态  3 1. 不能连接网络  4 2. 蜂窝连接  5 3.WiFi 连接  6 4. 未知连接  7 */ 8 static AFNetworkReachabilityStatus AFNetworkReachabilityStatusForFlags(SCNetworkReachabilityFlags flags) { 9 10 //  是否能够到达 11 BOOL isReachable = ((flags   kSCNetworkReachabilityFlagsReachable) != 0);12 13 //  在联网之前需要建立连接 14 BOOL needsConnection = ((flags   kSCNetworkReachabilityFlagsConnectionRequired) != 0);15 16 //  是否可以自动连接 17 BOOL canConnectionAutomatically = (((flags   kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) || ((flags   kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0));18 19 //  是否可以连接,在不需要用户手动设置的前提下 20 BOOL canConnectWithoutUserInteraction = (canConnectionAutomatically   (flags   kSCNetworkReachabilityFlagsInterventionRequired) == 0);21 22 //  是否可以联网的条件  1. 能够到达  2. 不需要建立连接或者不需要用户手动设置连接   就表示能够连接到网络 23 BOOL isNetworkReachable = (isReachable   (!needsConnection || canConnectWithoutUserInteraction));24 25 AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusUnknown;26 if (isNetworkReachable == NO) {27 status = AFNetworkReachabilityStatusNotReachable;28 }29 #if TARGET_OS_IPHONE30 else if ((flags   kSCNetworkReachabilityFlagsIsWWAN) != 0) {31 status = AFNetworkReachabilityStatusReachableViaWWAN;32 }33 #endif34 else {35 status = AFNetworkReachabilityStatusReachableViaWiFi;36 }37 38 return status;39 }

这个方法根据 SCNetworkReachabilityFlags 这个标记转换成我们自定义的枚举类型。至于转换规则,上边的代码中注释部分写的很清楚。

*** 在这里不得不多说几句,很多框架中都会把一个类中的私有方法写成这样。为什么呢?我们在开发中经常会写成 - (void)funcName; 这样的私有方法。

我个人的意见是一个类中的私有方法写成 static void funcName() 这样的 c 函数比较好。 

1. 在文件的最前方,比较容易查找

2. 可以适当的使用内联函数,提高效率。

如何解析 AFNetworking 框架的解读

根据一个标识 来处理 Block 和通知。保证两者同一状态。

如何解析 AFNetworking 框架的解读

包含了 类中需要处理的属性。

如何解析 AFNetworking 框架的解读

来看这个最基本的初始化方法,初始化了自身的属性。

CFRetain() 后要记得 CFRelease().

如何解析 AFNetworking 框架的解读

通过一个 socket 地址来初始化。首先新建  SCNetworkReachabilityRef 对象,然后调用 initWithReachability: 方法。记得手动管理内存。

如何解析 AFNetworking 框架的解读

这个方法基本同上。

综合上边两个方法,我们发现  SCNetworkReachabilityRef 有两个创建方法:

1. SCNetworkReachabilityCreateWithName 

2. SCNetworkReachabilityCreateWithAddress

如何解析 AFNetworking 框架的解读

由于 IPv6 是 ios9 和 os_x 10.11 后边推出的,所有要进行版本判断。这礼拜呢设计到的 socket 的知识,请看  socket 通信

通过这段代码我们能学到什么呢?

1,方法的创建也是有顺序的,可以使用函数访问函数的思想。

2. @if 这样的预编译指令能够替换掉代码中部分 if else。好处就是代码会不会被编译的区别。

如何解析 AFNetworking 框架的解读

单例的写法。

如何解析 AFNetworking 框架的解读

对需要释放时,做一些处理。

如何解析 AFNetworking 框架的解读

这个是.h 文件暴露出来的 3 个 BOOL 属性的 getter 方法,注意,由于我们在 @property 中定义了 getter 方法,所以 getter 方法就要写成我们定义的那种。

从这 3 个方法中也能看出,函数嵌套的思想还是很重要,要想做到这一点,只能是多想才行。

如何解析 AFNetworking 框架的解读

这个算是这个类的核心方法,设置监听网咯监听。

我们先来了解下基础知识。

SCNetworkReachabilityContext

点进去,会发现这是一个结构体,一般 c 语言的结构体是对要保存的数据的一种描述

如何解析 AFNetworking 框架的解读

1. 第一个参数接受一个 signed long 的参数

2. 第二个参数接受一个 void * 类型的值,相当于 oc 的 id 类型,void * 可以指向任何类型的参数

3. 第三个参数 是一个函数 目的是对 info 做 retain 操作,

4. 第四个参数是一个函数,目的是对 info 做 release 操作

5. 第五个参数是 一个函数,根据 info 获取 Description 字符串

在这里我们要携带的这个 info 就是下边的这个 block

 1 __weak __typeof(self)weakSelf = self; 2 AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) { 3 __strong __typeof(weakSelf)strongSelf = weakSelf; 4 5 strongSelf.networkReachabilityStatus = status; 6 if (strongSelf.networkReachabilityStatusBlock) { 7 strongSelf.networkReachabilityStatusBlock(status); 8 } 9 10 };

retain 和 release 函数是下边的这两个函数

1 static const void * AFNetworkReachabilityRetainCallback(const void *info) {2 return Block_copy(info);3 }4 5 static void AFNetworkReachabilityReleaseCallback(const void *info) {6 if (info) {7 Block_release(info);8 }9 }

设置网络监控分为下边几个步骤:

1. 我们先新建上下文

1 SCNetworkReachabilityContext context = {0, (__bridge void *)callback, AFNetworkReachabilityRetainCallback, AFNetworkReachabilityReleaseCallback, NULL};

2. 设置回调

1 SCNetworkReachabilitySetCallback(self.networkReachability, AFNetworkReachabilityCallback,  context);

其中这个 AFNetworkReachabilityCallback 是这样被定义的一个函数

typedef void (*SCNetworkReachabilityCallBack) (
 SCNetworkReachabilityRef target,
 SCNetworkReachabilityFlags flags, void * __nullable info
 );

在本类中

1 static void AFNetworkReachabilityCallback(SCNetworkReachabilityRef __unused target, SCNetworkReachabilityFlags flags, void *info) {2 AFPostReachabilityStatusChange(flags, (__bridge AFNetworkReachabilityStatusBlock)info);3 }

3. 加入 RunLoop 池

1 SCNetworkReachabilityScheduleWithRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);

其中 CFRunLoopGetMain() 代表主 RunLoop

ok,差不多已经完成

如何解析 AFNetworking 框架的解读

在异步线程 发送一次当前的网络状态。

 如何解析 AFNetworking 框架的解读

停止网络监控

如何解析 AFNetworking 框架的解读

这两个方法没什么好说的了,一个是 getter 一个是 setter 

如何解析 AFNetworking 框架的解读

注册键值依赖,这个可能大家平时用的比较少。可以了解一下

比如说一个类 User 中有两个属性

如何解析 AFNetworking 框架的解读 

还有一个卡片的类 card

如何解析 AFNetworking 框架的解读

  我们写一个 info 的 setter 和 getter   方法,

如何解析 AFNetworking 框架的解读

 1 @interface User :NSObject 2 @property (nonatomic,copy)NSString *name; 3 @property (nonatomic,assign)NSUInteger age; 4 @end 5 6 7 8 @interface card :NSObject 9 @property (nonatomic,copy)NSString *info;10 @property (nonatomic,strong)User *user;11 @end12 @implementation card13 14 - (NSString *)info {15 return [NSString stringWithFormat:@ %@/%lu ,_user.name,(unsigned long)_user.age];16 }17 - (void)setInfo:(NSString *)info {18 19 NSArray *array = [info componentsSeparatedByString:@ / 20 _user.name = array[0];21 _user.age = [array[1] integerValue];22 23 }24 25 + (NSSet NSString *  *)keyPathsForValuesAffectingValueForKey:(NSString *)key {26 NSSet * keyPaths = [super keyPathsForValuesAffectingValueForKey:key];27 NSArray * moreKeyPaths = nil;28 29 if ([key isEqualToString:@ info])30 {31 moreKeyPaths = [NSArray arrayWithObjects:@ user.name , @ user.age , nil];32 }33 34 if (moreKeyPaths)35 {36 keyPaths = [keyPaths setByAddingObjectsFromArray:moreKeyPaths];37 }38 39 return keyPaths;40 }41 42 @end

gh.dokee.cn/article/content-2292769-34004.html
gh.dokee.cn/article/content-2292768-34004.html
gh.dokee.cn/article/content-2292766-34004.html
gh.dokee.cn/article/content-2292765-34004.html
gh.dokee.cn/article/content-2292764-34004.html
gh.dokee.cn/article/content-2292763-34004.html
gh.dokee.cn/article/content-2292762-34004.html
gh.dokee.cn/article/content-2292761-34004.html
gh.dokee.cn/article/content-2292760-34004.html
gh.dokee.cn/article/content-2292759-34004.html
gh.dokee.cn/article/content-2292758-34004.html
bbs.open.qq.com/thread-15334805-1-1.html
bbs.open.qq.com/thread-15335348-1-1.html
bbs.open.qq.com/thread-15335576-1-1.html
bbs.open.qq.com/thread-15335715-1-1.html
http://bbs.open.qq.com/thread-15335916-1-1.html
http://bbs.open.qq.com/thread-15335876-1-1.html
http://bbs.open.qq.com/thread-15336398-1-1.html
http://bbs.open.qq.com/thread-15336484-1-1.html
http://bbs.open.qq.com/thread-15336547-1-1.html
http://bbs.open.qq.com/thread-15336614-1-1.html
http://bbs.open.qq.com/thread-15336697-1-1.html
http://bbs.open.qq.com/thread-15336806-1-1.html
http://bbs.open.qq.com/thread-15340763-1-1.html
www.baiyewang.com/s4209086.html
http://bl.gamebbs.qq.com/forum.php?mod=viewthread tid=11675819
http://bbs.open.qq.com/thread-15343974-1-1.html
http://bbs.open.qq.com/thread-15344107-1-1.html
http://caimi68.lofter.com/post/1e3e0a7a_bbb5392
http://caimi68.lofter.com/post/1e3e0a7a_bbb539f
http://caimi68.lofter.com/post/1e3e0a7a_bbb539e
http://caimi68.lofter.com/post/1e3e0a7a_bbb539d
http://caimi68.lofter.com/post/1e3e0a7a_bbb539c
http://caimi68.lofter.com/post/1e3e0a7a_bbb53a0
http://caimi68.lofter.com/post/1e3e0a7a_bbb53a1
http://caimi68.lofter.com/post/1e3e0a7a_bbb53a2
http://caimi68.lofter.com/post/1e3e0a7a_bbb53a4
http://bbs.open.qq.com/thread-15345770-1-1.html
http://bbs.open.qq.com/thread-15345813-1-1.html
http://bbs.open.qq.com/thread-15345854-1-1.html
http://bbs.open.qq.com/thread-15345888-1-1.html
http://bbs.open.qq.com/thread-15345937-1-1.html
http://bbs.open.qq.com/thread-15346013-1-1.html
http://bbs.open.qq.com/thread-15346046-1-1.html
http://bbs.open.qq.com/thread-15346098-1-1.html
http://bbs.open.qq.com/thread-15346138-1-1.html
http://bbs.open.qq.com/thread-15346194-1-1.html
http://bbs.open.qq.com/thread-15346240-1-1.html
http://bbs.open.qq.com/thread-15346345-1-1.html
http://g.jandan.net/s/6319
http://g.jandan.net/s/6320
http://g.jandan.net/s/6321
http://g.jandan.net/s/6322
http://g.jandan.net/s/6323

以上就是如何解析 AFNetworking 框架的解读的全部内容了,更多与如何解析 AFNetworking 框架的解读相关的内容可以搜索丸趣 TV 之前的文章或者浏览下面的文章进行学习哈!相信丸趣 TV 小编会给大家增添更多知识, 希望大家能够支持一下丸趣 TV!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-07-15发表,共计10155字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)