久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

如何解析AFNetworking框架的解讀

149次閱讀
沒有評論

共計 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字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 哈密市| 吉安县| 康马县| 商南县| 新巴尔虎左旗| 武威市| 昌邑市| 响水县| 昌江| 太白县| 新丰县| 宜都市| 大名县| 嘉黎县| 成武县| 永城市| 齐齐哈尔市| 香格里拉县| 合肥市| 五指山市| 万年县| 阿拉尔市| 南京市| 砚山县| 沙田区| 徐州市| 达拉特旗| 孟州市| 璧山县| 西和县| 庆阳市| 柏乡县| 城口县| 巨野县| 清徐县| 策勒县| 泰兴市| 磐安县| 苏州市| 华容县| 溧水县|