| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 移动开发 -> iOS基础框架深究之AFNetWorking day 1 -> 正文阅读 |
|
[移动开发]iOS基础框架深究之AFNetWorking day 1 |
我工作6年半,一直从事业务层面的开发,iOS底层相关的东西也只是通过视频去做了解,随着年龄的变化,会发现以后的路会越来越窄,学习这个东西什么时候开始学都不晚,说不定什么时候会给你带来意想不到的事情,别管别的事情了,最起码从现在开始,慢慢丢弃身边的杂事,不要在乎眼前的那点利益,也不要刻意追求什么,踏下心做好一件事,花更多的时间在接触知识上,这是今天我对自己说的话。也是以过来人给大家的一个忠告。接下来探索一下一些优秀的开源框架,希望有一天我们,总有一天我们可以搭建出更好的框架。 AFNetWorking这个网络框架我们都非常熟悉,无论是日常的使用还是面试,其实我们只是觉得他是做网络请求的,刚接触的时候只知道用post get方法,接触http协议后有可能会用到put delete等方法,对于它内部的实现原理我们并没有做深究,今天往后的一段时间里我们将深究其中,揭开他神奇的面纱,不要给别人说我会用了。本系列以AFNetWorking 3.0作为源码解读。 我们先看看整个框架的一个逻辑,我们先看一个监控网络环境变化的类AFNetworkReachabilityManager #import <SystemConfiguration/SystemConfiguration.h> 通过导入了这个头文件,我们知道网络监控的实现是依赖?SystemConfiguration这个api的。说明这个api可以提供这样的功能。 ?这是一个枚举封装,还是遵循一个使用枚举的原则,当满足一个有限的并具有统一主题的集合的时候,我们就考虑枚举。网络上这4种类型基本能满足我们开发中的大部分功能。 四个属性均为只读属性,只给了用户访问权,注意BOOL属性一般要写成getter方法的。? 提供了5种初始化方法,能够满足大部分的需求。 SCNetworkReachabilityRef 这个很重要,这个类的就是基于它开发的。? + (instancetype)managerForDomain:(NSString *)domain; 监听制定domain网络状态 + (instancetype)managerForAddress:(const void *)address;监听某个socket地址的网络状态,socket通信请看这里c 网络与套接字socket - 马在路上 - 博客园 打开和关闭监听的方法 ? 返回一个网络状态的本地语言的字符串。往往我们可以根据这个字符串来告诉用户,当前网络发生了什么,当然,也可以根据状态自定义提示文字。 ? 设置网络状态改变的回调,监听网络改变回调的两种方式: 1.使用上面的这个方法。 2.监听AFNetworkingReachabilityDidChangeNotification通知。 ? 这个是与网络状态变化相关的通知,接受的通知中会有一个userinfo是一个NSDictionary其中key就是AFNetworkingReachabilityNotificationStatusItem *** 这简单的两行代码能够告诉我们的是,我们平时的开发中 但凡设计到发通知的功能,我们应该把通知的字符串封装到一个专有的文件中,同时在文件内部按不同模块进行区分,当然必要的注释也很有必要。? ps:?FOUNDATION_EXPORT 和#define 都能定义常量。FOUNDATION_EXPORT 能够使用==进行判断,效率略高。而且能够隐藏定义细节(就是实现部分不在.中) ?对函数:根据状态获取字符串声明。 好了,这个类的.h文件我们已经进行解读了,我们并不是大概说下他提供的功能,而是通过每一行代码,我们能联想到什么,什么东西能帮助我们更好的编程。 我们接着看AFNetworkReachabilityManager.m 的内容 这几个头文件是系统库,是为了后边sockaddr_?in6/sockaddr_in准备的,不熟悉的可以看这篇文章c 网络与套接字socket - 马在路上 - 博客园 这几个就没什么好说的,我们接着看 ?这个方法是对.h中最后一个方法的实现,指的我们注意是NSLocalizedStringFromTable这个宏,为什么要注意它呢? 这就涉及到本地国际化的问题。所谓的国际化就是让你的app能够根据不同的语言显示相对应的语言。 但这并不简单,没有经验的开发人员,一开始可能不会做这样的设置,如果日后需要国际话了,在做就很麻烦了。所以说在开发中,但凡用到字符串的地方都要考虑语言的不同。不同的语言下,一个意思的表达所使用的字符串长度是不一样的,这就映射出空间的宽度可能会不一样。 好了,国际化的内容就不说了,请自行搜索。 这个方法根据SCNetworkReachabilityFlags这个标记转换成我们自定义的枚举类型。至于转换规则,上边的代码注释部分写的很清楚。 ***在这里不得不多说几句,很多框架中都会把一个类中的私有方法写成这样。为什么呢?我们在开发中经常写成-(void)funcName;这样的私有方法。 我个人的意见是一个类中的私有方法写成static void funcName() 这样的函数比较好 1.在文件的最前方,比较容易查找 2.可以适当的使用内联函数,提高效率。 ? ?根据一个标识 来处理Block和通知。保证两者同一状态。 包含了 类中需要处理的属性 ?来看这个最基本的初始化方法,初始化了自身的属性。 CFRetain()后记得CFRelease() 通过一个socket地址来初始化。首先新建SCNetworkReachabilityRef对象,然后调用initWithReachability:方法。记得手动管理内存。 这个方法基本同上。 综合上边两个方法,我们发现SCNetworkReachabilityRef有两个创建方法: 1.SCNetworkReachabilityCreateWithName 2.SCNetworkReachabilityCreateWithAddress ? ?由于IPV6是iOS9和os_x 10.11后边推出的,所有要进行版本判断。 1.方法的创建也是有顺序的,可以使用函数访问函数的思想。 2.@if这样的预编译指令能够替换掉代码中部分if else。好处就是代码会不会被编译的区别。 单例的写法 ?对于需要释放时,做一些处理 ?这个是.h文件暴露出来的三个BOOL属性的getter方法,注意,由于我们在@property中定义了getter方法,所以getter方法就要写成我们定义的那种。从这三个方法中也能看出,函数嵌套的思想还是很重要,要想做到这一点,只能是多想才行。 ? 这个算是这个类的核心方法,设置监听网络监听 我们先来了解下基础知识 ?SCNetworkReachabilityContext 点进去,会发现这是一个结构体,一般C语言的结构体是对要保护的数据的一种描述 1.第一个参数接受一个signed long的参数 2.第二个参数接受一个void *类型的值,相当于oc的id类型,void*可以指向任何类型的参数 3.第三个参数 是一个函数 目的是对info做retain操作 4.第四个参数是一个函数,目的是对info做release操作 5.第五个参数是一个函数,根据info获取Description字符串 在这里我们要携带的这个info就是下边的这个block ? ?retain和release函数是下边的这两个函数 设置网络监控分为下边几个步骤 1.我们先新建上下文 1 SCNetworkReachabilityContext context = {0, (__bridge void *)callback, AFNetworkReachabilityRetainCallback, AFNetworkReachabilityReleaseCallback, NULL}; 2.设置回调 1 SCNetworkReachabilitySetCallback(self.networkReachability, AFNetworkReachabilityCallback, &context); ?其中这个AFNetworkReachabilityCallback是这样被定义的一个函数 在本类中 static void AFNetworkReachabilityCallback(SCNetworkReachabilityRef __unused target, SCNetworkReachabilityFlags flags, void *info) { ????????AFPostReachabilityStatusChange(flags, (__bridge AFNetworkReachabilityStatusBlock)info); } 3.加入RunLoop池 SCNetworkReachabilityScheduleWithRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes); 其中CFRunLoopGetMain()代表主RunLoop ok,差不多已经完成 在异步线程 发送一次当前的网络状态 ?停止网络监控 ?这两个方法没什么好说的,一个是getter 一个是setter ?注册键值依赖,这个可能大家平时用的比较少。可以了解一下 比如说一个类User中有两个属性 还有一个卡片的类card ?我们写一个info的setter和getter方法, ? ? ? 代码差不多就是上边的。我们可以监听card的info属性,当user中的name或者age值发生改变的时候,就会触发info的键值监听方法。这就是键值依赖的作用。 东西不少,一点点打出来不易,慢慢消化两天吧。? ? ? |
|
移动开发 最新文章 |
Vue3装载axios和element-ui |
android adb cmd |
【xcode】Xcode常用快捷键与技巧 |
Android开发中的线程池使用 |
Java 和 Android 的 Base64 |
Android 测试文字编码格式 |
微信小程序支付 |
安卓权限记录 |
知乎之自动养号 |
【Android Jetpack】DataStore |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 5:53:56- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |