面试题答案
一键面试AFNetworking 网络请求队列管理
- AFURLSessionManager 简介
AFURLSessionManager
是 AFNetworking 中负责管理NSURLSession
相关操作的类,它在网络请求队列管理方面起着关键作用。
- 核心代码逻辑 - 请求添加
AFURLSessionManager
通过dataTaskWithRequest:completionHandler:
等方法创建NSURLSessionDataTask
等任务。例如:
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler { __block NSURLSessionDataTask *dataTask = nil; dataTask = [self.session dataTaskWithRequest:request completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseData, NSError * _Nullable error) { [self URLSession:self.session task:dataTask didCompleteWithError:error]; if (completionHandler) { completionHandler(response, responseData, error); } }]; return dataTask; }
- 这里创建了一个
NSURLSessionDataTask
,并将其与特定的请求和完成处理程序关联。当调用resume
方法时,任务会被添加到NSURLSession
的请求队列中执行。
- 核心代码逻辑 - 请求暂停
AFURLSessionManager
中的任务(如NSURLSessionDataTask
)本身有suspend
方法。例如,当我们有一个NSURLSessionDataTask
实例task
时,可以调用[task suspend]
暂停任务。- 在
AFURLSessionManager
层面,它会跟踪任务的状态。例如,如果要暂停所有任务,可以遍历所有任务并调用其suspend
方法。虽然 AFNetworking 没有直接提供暂停所有任务的公开便捷方法,但理论上可以通过遍历tasks
数组(NSURLSession
有方法获取其管理的任务数组)来实现。
- 核心代码逻辑 - 请求取消
- 同样,
NSURLSessionDataTask
有cancel
方法,如[task cancel]
。AFURLSessionManager
会在任务取消时进行相应处理,例如在URLSession:task:didCompleteWithError:
方法中,当错误的code
表示任务取消时,会进行一些清理和通知操作。 - 例如:
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { if (error && error.code == NSURLErrorCancelled) { // 处理任务取消相关逻辑,如通知 delegate 等 } // 其他任务完成处理逻辑 }
- 同样,
- 线程安全保证
- 使用 GCD:AFNetworking 大量使用 Grand Central Dispatch(GCD)来处理多线程问题。例如,在更新任务状态、通知 delegate 等操作时,会在主队列或特定的队列中执行。比如在
URLSession:task:didCompleteWithError:
方法中,通知 delegate 的操作会在主队列中执行,以确保 UI 更新等操作的线程安全。
dispatch_async(dispatch_get_main_queue(), ^{ if ([self.delegate respondsToSelector:@selector(afURLSessionManager:task:didCompleteWithError:)]) { [self.delegate afURLSessionManager:self task:task didCompleteWithError:error]; } });
- 锁机制:在一些需要保护共享资源(如任务状态的跟踪数据结构)的地方,可能会使用锁机制。虽然 AFNetworking 源码中没有大量显式使用
NSLock
等传统锁,但通过 GCD 的队列同步机制,同样可以达到保护共享资源的目的。例如,对任务状态的更新操作可能在一个特定的串行队列中执行,避免多个线程同时修改导致数据不一致。
- 使用 GCD:AFNetworking 大量使用 Grand Central Dispatch(GCD)来处理多线程问题。例如,在更新任务状态、通知 delegate 等操作时,会在主队列或特定的队列中执行。比如在