標籤:多線程 patch request對象 erro 調試 方法 net 建立 res
Core檔案夾: Alamofire.swift - - - 該檔案中主要是給使用者提供一些便利的調用方法,使用者可以直接調用該檔案中的便利方法來使用Alamofire相關功能。 Manager.swift - - - Manager中定義了Session對象,Session相關的Delegate,以及Delegate執行的隊列等相關資訊,在Manager中建立Request對象發起請求。Manager管理的就是各種請求,Manager對象是以單例的形式對外開放的。 Request.swift - - - 該檔案如其名,就是負責建立Session的各種task的,並執行相關的SessionTask,並調用相關書籍解析的功能模組對資料進行解析並通過回調返回給使用者。 ParameterEncoding.swift - - - 負責請求參數的各種編碼(URL、URLEncodeInURL、JSON、PropertyList等編碼),並將編碼之後的資料與URLRequest結合後的結果進行返回。 Result.swift - - - 對解析後的資料封裝成Result對象; Response.swift - - - 負責將伺服器相應的資料進行封裝產生Response對象,該對象中就包括上述的Result對象,使用者最終工會通過閉包回調的形式擷取到該Response的對象。 Notifications.swift - - - 其實是一個Notification結構體,該結構體中定義了一些字串,這些字串就是所需通知的key,當網路請求DidResume、DIdSuspend、DIdCancel、DidComplete都會發出通知。 Error.swift - - - 其實是一個Error的結構體,其中封裝的是各種錯誤狀態。 Features檔案夾: Download.swift - - - 對Manager和Request類進行擴充,使其支援Download Task,其中封裝了NSURLSessionDownloadDelegate相關代理方法。 Upload.swift - - - 在該檔案中格式對Manager和Request類進行的擴充,使其支援Upload Task,其中封裝了NSURLSessionDataDelegate中擷取上傳資料進度的代理方法,也就是taskDidSendBodyData代理方法。 MultipartFormData.swift - - - 該檔案從名字就可以看出是為了組織多表單資料上傳的資料的,在Upload task中就使用到了MultipartFormData。 Stream.swift - - - 和Download和Upload檔案相似,該檔案中也是對Manager和Request做延展,主要使其支援資料流的傳輸,其中主要封裝和實現了NSURLSessionStreamDelegate相關的代理方法。 ResponseSerialization.swift - - - 該檔案中主要是對Request類進行資料解析的延展的。其中封裝了各種對響應資料的解析方式,其中包括Data、String、JSON、PropertyList等解析方式。 NetworkReachabilityManager.swift - - - 該檔案主要是對SystemConfiguration.framework中的SCNetworkReachability相關的東西進行封裝,主要用來管理和監聽網路狀態的變化。 ServerTrustPolicy.swift - - - 這個檔案主要是對NSURLSession做的延展,其中定義了各種網路請求的認證策略,主要認證認證相關東西。 Tileline.swift - - - 該檔案主要為了方便調試而生,其中記錄了相關操作的時間點,並且對其進行記錄,便於在Debug時使用到。 Validation.swift - - - 主要是用來驗證請求是否成功,如果出錯了就做相應的處理。 2、我的理解:Alamofire在實現中的特點;(1)、根據URL產生task是使用dispatch_sync進行(防止多線程問題,task的產生在一個線程內); dispatch_sync(queue) { dataTask = self.session.dataTaskWithRequest(URLRequest.URLRequest) } (2)、TaskDelegate的定義在Request類中,以類中類的方式存在,且只繼承於NSObject; (3)、SessionDelegate擴充了下標方法,下標方法中,取使用同步的dispatch取,存則使用dispatch_barrier_async去存,barrier的task會在這個concurrent的queue中的所有在自己之前開始執行的任務執行完成後再開始,同樣在自己之後提交到這個concurrent的queue中的任務也會在自己執行完成之後開始執行;這樣做很好的避免了資源競爭引起的資料不同步; 同時,SessionDelegate中設定了 subdelegates 的 [Int : Request.TaskDelegate] 索引值對來分發delegate的回調處理;下標方法操作的就是 subdelegate ,而且在get方法中,根據參數的task的taskIdentifier來取得對應的delegate,且擷取的步驟使用了sync的同步操作;??????????,不太明白為什麼;而在set方法中,是使用了barrier 的方法來賦值新值;使用的依然是全域的subdelegateQueue,set裡面之所以使用 barrier 可能是因為這個隊列是全域使用的,為了防止我再存入新的值的時候會有調用;但是一個task對應一個taskIdentifier應該也不會重複的吧;??????? (4)、具體請求的響應; DataTaskDelegate、DownloadTaskDelegate、UploadTaskDelegate都是繼承於TaskDelegate,而在TaskDelegate中有一個 NSOperationQueue 類型的屬性 queue ,因為繼承關係,這三個delegate中也是有這個變數的;同樣在TaskDelegate的初始化中,也初始化了這個queue;且初始的suspended為true,maxConcurrentOperationCount為1;初始化部分使用了匿名方法的方式進行;對應的,在deist方法中調用了queue的cancelAllOperations方法和suspended設為了false;且當接收到資料後才會被置為false,此時它內部添加的operation即response的解析化才回真正執行,解析後執行回調completionHandler 也就是說其實請求成功執行的回調其實封裝在了一個在=operation上,而一個delegate有一個queue,一個queue中只有一個operation,而queue在建立的時候開始都是暫停,直到收到資料,這一個請求的代理方法回去開啟自己對應的queue,而因為queue已經開啟,之前添加的operation開始執行; 這裡也有另外一點,DataTaskDelegate、DownloadTaskDelegate、UploadTaskDelegate三個delegate,雖然是名字中有delegate,但並不是單純的protocol,而是聲明為了class ,但是其中實現了NSURLSessionDataDelegate、NSURLSessionDownloadDelegate協議方法;其中UploadTaskDelegate繼承於DataTaskDelegate (5)、一個請求發生的方法調用; 調用request(...)公用方法1 -> 1中調用了 Manager.shareInstance.request(…) 2 -> 2中調用了該單例中的另一 request(…) 方法3 -> 3中調用了 Request(…) 方法4,建立一個Request對象 -> 4中調用了 DataTaskDelegate(…) 方法5來初始化一個TaskDelegate的子類,而在建立這個子類時,也就有了類型為NSOperationQueue的變數queue(初始為暫停),同時也添加了一個operation -> 因為5其實是帶有代理回調的,所以請求結束後,會觸發系統session的毀掉方法,再進行傳遞; 這樣的處理方式,其實是一個請求一個Request對象,Request對象中包含一個delegate對象,也就對應了一個queue,因為queue只維護一個operation,而一個請求的發起和回調都是在一個operation上面進行,從而保證資料請求不會錯亂,不會是A請求的結果卻回調了B請求的回調的執行;還因為A和B都不是一個線程; 參考:http://www.cocoachina.com/ios/20151117/14240.html 這一篇文章講的很好,剛開始我自己看源碼確實理不清這些關係,對著這個一個類一個類的看下去,才終於明白了整個的調用層次; http://www.cnblogs.com/ludashi/p/5588044.html 這篇文章會告訴你每個類都做了什麼
Alamofire源碼學習