最近看了下AFNetworking3.0的代碼桥温,發(fā)現(xiàn)大師寫的代碼有很多亮點(diǎn)扑浸,其中我覺得最可以借鑒的是模塊的解耦性烧给。
解耦性
應(yīng)用方使用AF一般只會用到AFHTTPSessionManger類,而這個類只不過是封裝了AFURLSessionManger類的方法喝噪,所以主要功能的實(shí)現(xiàn)都在AFURLSessionManger類础嫡。
AFURLSessionManger類里面是如何解耦的呢?其中最主要的是酝惧,定義了一個字典
@property (readwrite, nonatomic, strong) NSMutableDictionary *mutableTaskDelegatesKeyedByTaskIdentifier;
該mutableTaskDelegatesKeyedByTaskIdentifier的key值為NSURLSessionTask.taskIdentifier(一個NSURLSessionTask任務(wù)的id標(biāo)識)榴鼎,value值為AFURLSessionManagerTaskDelegate伯诬。
而AFURLSessionManager需要實(shí)現(xiàn)的NSURLSessionTaskDelegate, NSURLSessionDataDelegate, NSURLSessionDownloadDelegate代理,主要都是通過mutableTaskDelegatesKeyedByTaskIdentifier字典拋回給AFURLSessionManagerTaskDelegate里去實(shí)現(xiàn)巫财,實(shí)現(xiàn)完成的值又通過block回調(diào)給AFURLSessionManager里面的block盗似。
具體流程:
1、 AFURLSessionManager新建一個Task時翁涤,把Task與AFURLSessionManagerTaskDelegate通過字典mutableTaskDelegatesKeyedByTaskIdentifier聯(lián)系起來
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request
uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgressBlock
downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgressBlock
completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler {
__block NSURLSessionDataTask *dataTask = nil;
url_session_manager_create_task_safely(^{
dataTask = [self.session dataTaskWithRequest:request];
});
[self addDelegateForDataTask:dataTask uploadProgress:uploadProgressBlock downloadProgress:downloadProgressBlock completionHandler:completionHandler];
return dataTask;
}
其中關(guān)鍵代碼:
[self addDelegateForDataTask:dataTask uploadProgress:uploadProgressBlock downloadProgress:downloadProgressBlock completionHandler:completionHandler];
- (void)addDelegateForDataTask:(NSURLSessionDataTask *)dataTask
uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgressBlock
downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgressBlock
completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
{
AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] initWithTask:dataTask];
delegate.manager = self;
delegate.completionHandler = completionHandler;
dataTask.taskDescription = self.taskDescriptionForSessionTasks;
[self setDelegate:delegate forTask:dataTask];
delegate.uploadProgressBlock = uploadProgressBlock;
delegate.downloadProgressBlock = downloadProgressBlock;
}
2桥言、在回調(diào)函數(shù)中,把需要實(shí)現(xiàn)的委托葵礼,拋回給AFURLSessionManagerTaskDelegate去實(shí)現(xiàn),拋回后從字典中移除該Task
- (void)URLSession:(NSURLSession *)session
task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error
{
AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:task];
// delegate may be nil when completing a task in the background
if (delegate) {
[delegate URLSession:session task:task didCompleteWithError:error];
[self removeDelegateForTask:task];
}
if (self.taskDidComplete) {
self.taskDidComplete(session, task, error);
}
}
其中關(guān)鍵代碼為:
[delegate URLSession:session task:task didCompleteWithError:error];
[self removeDelegateForTask:task];
3并鸵、AFURLSessionManagerTaskDelegate去實(shí)現(xiàn)該委托鸳粉,實(shí)現(xiàn)完成后把結(jié)果給self.completionHandler 的block值,從而就把該值傳遞給了應(yīng)用層的completionHandler
- (void)URLSession:(__unused NSURLSession *)session
task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error
{
__strong AFURLSessionManager *manager = self.manager;
__block id responseObject = nil;
__block NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
userInfo[AFNetworkingTaskDidCompleteResponseSerializerKey] = manager.responseSerializer;
//Performance Improvement from #2672
NSData *data = nil;
if (self.mutableData) {
data = [self.mutableData copy];
//We no longer need the reference, so nil it out to gain back some memory.
self.mutableData = nil;
}
if (self.downloadFileURL) {
userInfo[AFNetworkingTaskDidCompleteAssetPathKey] = self.downloadFileURL;
} else if (data) {
userInfo[AFNetworkingTaskDidCompleteResponseDataKey] = data;
}
if (error) {
userInfo[AFNetworkingTaskDidCompleteErrorKey] = error;
dispatch_group_async(manager.completionGroup ?: url_session_manager_completion_group(), manager.completionQueue ?: dispatch_get_main_queue(), ^{
if (self.completionHandler) {
self.completionHandler(task.response, responseObject, error);
}
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidCompleteNotification object:task userInfo:userInfo];
});
});
} else {
dispatch_async(url_session_manager_processing_queue(), ^{
NSError *serializationError = nil;
responseObject = [manager.responseSerializer responseObjectForResponse:task.response data:data error:&serializationError];
if (self.downloadFileURL) {
responseObject = self.downloadFileURL;
}
if (responseObject) {
userInfo[AFNetworkingTaskDidCompleteSerializedResponseKey] = responseObject;
}
if (serializationError) {
userInfo[AFNetworkingTaskDidCompleteErrorKey] = serializationError;
}
dispatch_group_async(manager.completionGroup ?: url_session_manager_completion_group(), manager.completionQueue ?: dispatch_get_main_queue(), ^{
if (self.completionHandler) {
self.completionHandler(task.response, responseObject, serializationError);
}
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidCompleteNotification object:task userInfo:userInfo];
});
});
});
}
}
其中關(guān)鍵代碼為
if (self.completionHandler) {
self.completionHandler(task.response, responseObject, error);
}
總結(jié)
其實(shí)就是把需要實(shí)現(xiàn)的Delegate值交給一個類去實(shí)現(xiàn)园担,好處是避免了隨著業(yè)務(wù)不斷發(fā)展出現(xiàn)回調(diào)函數(shù)里代碼過長届谈,而且直觀性比較強(qiáng),可以在我們工作中借鑒這種寫法弯汰。最后艰山,如果想看關(guān)于AF較為詳細(xì)的源碼分析,可以推薦看看這篇文章:
《AFNetworking到底做了什么》