这个是网络请求方法调用的顺序。**改为99
2020-06-10
最近在看SVProgressHUD,一头雾水。
又回头看了看AF找找自信,把我这边博客找出来看看(其实写的不好)。看完之后有些感慨要发下,不然会憋出内伤的。
刚开始看AF,也是一头雾水。无从下手最能体现我当时的现状,看看懂然后百度,谷歌查AF源码解读,放到一边不管不问。如此循环,我就想着自己不是开发的料,第三方开源都看不出点啥东西。如果不是生活我本来就不想再看Af,可是看到招聘写的技能要求,我就又狠心看一遍,反正是被虐的怀疑人生。但是我还是给每次看到新的知识加注释,就这样我慢慢发现Af也是能够看懂了(只是心理知道他的逻辑调用)。然后出了问题知道怎么取查问题!!希望自己坚持把svp整理出来吧。
2020-05-25
线程调用顺序
这里 #0 #1 #2 #3 #4 #5 #6 #7 都是线程
#0 -[AFURLSessionManager addNotificationObserverForTask:] #1 -[AFURLSessionManager setDelegate:forTask:] #2 -[AFURLSessionManager addDelegateForDataTask:uploadProgress:downloadProgress:completionHandler:] #3 -[AFURLSessionManager dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler:] #4 -[AFHTTPSessionManager dataTaskWithHTTPMethod:URLString:parameters:headers:uploadProgress:downloadProgress:success:failure:] #5 -[AFHTTPSessionManager POST:parameters:headers:progress:success:failure:] #6 -[ZLJNetViewController postNetWorking] #7 -[ZLJNetViewController touchesBegan:withEvent:]
#7 我添加的点击方法
#6 我自己写的pos请求
#5 这个线程是被线程#6调用的方法 -- 添加请求类型-POST,其他都在#4中处理。#4会返回一个dataTask(NSURLSessionDataTask)
#4 是线程#5调用的方法 -- 1.构建请求NSMutableURLRequest (其他设置) 2.请求回来的数据处理,用block(completionHandler:^(......))处理失败/成功数据。reques/uploadProgress/downloadProgress交给#3处理,#3返回dataTask
#3 是线程#4调用的方法 -- 没做实事,交给#2做处理。创建dataTask对象。
#2 是线程#3调用的方法 -- 1.manager(AFURLSessionManager)和delegate(AFURLSessionManagerTaskDelegate)进行关联(网上看到的解释)。给manager设置delegate。上传/下载block赋值。
#1 是线程#2调用的方法 -- 根据task发通知出去(2个通知)
#0 是线程#1调用的方法 -- 发出2个通知1.开始请求(taskDidResume),2.暂停请求(taskDidSuspend)。
******************************************************************************************************
上面处理完成之后,线程#5中的 dataTask调用方法[dataTask resume];//开始请求
请求之后在delegate方法中有返回结果。 这个是系统delegate方法 --请求结束或失败时调用
#0 -[AFURLSessionManagerTaskDelegate URLSession:task:didCompleteWithError:]
2020-05-23
#pragma mark -- POST - (void)postNetWorking{//1 NSString *urlString = [NSString stringWithFormat:@"/cgi-bin/courseDetail_json?course_id=52**3"]; NSURL *baseUrl = [NSURL URLWithString:@"http://ke.qq.com/"]; AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:baseUrl]; manager.responseSerializer = [AFJSONResponseSerializer serializer]; manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"application/json"]; NSLog(@"zlj--当前输出A1:%s",__FUNCTION__); [manager POST:urlString parameters:nil headers:nil progress:^(NSProgress * _Nonnull uploadProgress) { NSLog(@"downloadProgress --- :%s",__FUNCTION__); } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSLog(@"zlj--当前输出success:%s",__FUNCTION__); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { NSLog(@"zlj--当前输出failure:%s",__FUNCTION__); }]; }
1.AFHTTPSessionManager : AFURLSessionManager
1- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(nullable id)parameters headers:(nullable NSDictionary <NSString *, NSString *> *)headers progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure { 2- (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method URLString:(NSString *)URLString parameters:(nullable id)parameters headers:(nullable NSDictionary <NSString *, NSString *> *)headers uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgress downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgress success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure {
2.AFURLSessionManager
3- (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 { 4- (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 {
5- (void)setDelegate:(AFURLSessionManagerTaskDelegate *)delegate forTask:(NSURLSessionTask *)task {//7 NSLog(@"zlj--当前输出A10:%s",__FUNCTION__); NSParameterAssert(task); NSParameterAssert(delegate); [self.lock lock]; self.mutableTaskDelegatesKeyedByTaskIdentifier[@(task.taskIdentifier)] = delegate; [self addNotificationObserverForTask:task]; [self.lock unlock]; } 6 - (void)addNotificationObserverForTask:(NSURLSessionTask *)task { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskDidResume:) name:AFNSURLSessionTaskDidResumeNotification object:task]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskDidSuspend:) name:AFNSURLSessionTaskDidSuspendNotification object:task]; }
@interface _AFURLSessionTaskSwizzling : NSObject
@end
这个类是发出通知(上面的2个通知),
ps:现在不知道的就是,这个类 +laod{}是什么时候调用的。2020-05-23
/***************************************************************************************************************** 分割线 *******************************************************************************************/
@interface AFURLSessionManagerTaskDelegate : NSObject <NSURLSessionTaskDelegate, NSURLSessionDataDelegate, NSURLSessionDownloadDelegate> @interface _AFURLSessionTaskSwizzling : NSObject @interface AFURLSessionManager ()
这个文件里面有三个 @interface,真是让我大吃一惊。不弄死死真难平我心头之恨!!!草
static dispatch_queue_t url_session_manager_processing_queue() { static dispatch_queue_t af_url_session_manager_processing_queue; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ //会话管理处理队列 af_url_session_manager_processing_queue = dispatch_queue_create("com.alamofire.networking.session.manager.processing", DISPATCH_QUEUE_CONCURRENT); }); return af_url_session_manager_processing_queue; } static dispatch_group_t url_session_manager_completion_group() { static dispatch_group_t af_url_session_manager_completion_group;//会话管理完成 static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ af_url_session_manager_completion_group = dispatch_group_create(); }); return af_url_session_manager_completion_group; }
开头2个C函数,蒙了不知道啥意思!!!!
NSString * const AFNetworkingTaskDidResumeNotification = @"com.alamofire.networking.task.resume"; NSString * const AFNetworkingTaskDidCompleteNotification = @"com.alamofire.networking.task.complete"; NSString * const AFNetworkingTaskDidSuspendNotification = @"com.alamofire.networking.task.suspend"; NSString * const AFURLSessionDidInvalidateNotification = @"com.alamofire.networking.session.invalidate"; NSString * const AFURLSessionDownloadTaskDidMoveFileSuccessfullyNotification = @"com.alamofire.networking.session.download.file-manager-succeed"; NSString * const AFURLSessionDownloadTaskDidFailToMoveFileNotification = @"com.alamofire.networking.session.download.file-manager-error"; NSString * const AFNetworkingTaskDidCompleteSerializedResponseKey = @"com.alamofire.networking.task.complete.serializedresponse"; NSString * const AFNetworkingTaskDidCompleteResponseSerializerKey = @"com.alamofire.networking.task.complete.responseserializer"; NSString * const AFNetworkingTaskDidCompleteResponseDataKey = @"com.alamofire.networking.complete.finish.responsedata"; NSString * const AFNetworkingTaskDidCompleteErrorKey = @"com.alamofire.networking.task.complete.error"; NSString * const AFNetworkingTaskDidCompleteAssetPathKey = @"com.alamofire.networking.task.complete.assetpath"; NSString * const AFNetworkingTaskDidCompleteSessionTaskMetrics = @"com.alamofire.networking.complete.sessiontaskmetrics"; static NSString * const AFURLSessionManagerLockName = @"com.alamofire.networking.session.manager.lock"; typedef void (^AFURLSessionDidBecomeInvalidBlock)(NSURLSession *session, NSError *error); typedef NSURLSessionAuthChallengeDisposition (^AFURLSessionDidReceiveAuthenticationChallengeBlock)(NSURLSession *session, NSURLAuthenticationChallenge *challenge, NSURLCredential * __autoreleasing *credential); typedef NSURLRequest * (^AFURLSessionTaskWillPerformHTTPRedirectionBlock)(NSURLSession *session, NSURLSessionTask *task, NSURLResponse *response, NSURLRequest *request); typedef NSURLSessionAuthChallengeDisposition (^AFURLSessionTaskDidReceiveAuthenticationChallengeBlock)(NSURLSession *session, NSURLSessionTask *task, NSURLAuthenticationChallenge *challenge, NSURLCredential * __autoreleasing *credential); typedef id (^AFURLSessionTaskAuthenticationChallengeBlock)(NSURLSession *session, NSURLSessionTask *task, NSURLAuthenticationChallenge *challenge, void (^completionHandler)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential)); typedef void (^AFURLSessionDidFinishEventsForBackgroundURLSessionBlock)(NSURLSession *session); typedef NSInputStream * (^AFURLSessionTaskNeedNewBodyStreamBlock)(NSURLSession *session, NSURLSessionTask *task); typedef void (^AFURLSessionTaskDidSendBodyDataBlock)(NSURLSession *session, NSURLSessionTask *task, int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend); typedef void (^AFURLSessionTaskDidCompleteBlock)(NSURLSession *session, NSURLSessionTask *task, NSError *error); #if AF_CAN_INCLUDE_SESSION_TASK_METRICS typedef void (^AFURLSessionTaskDidFinishCollectingMetricsBlock)(NSURLSession *session, NSURLSessionTask *task, NSURLSessionTaskMetrics * metrics) AF_API_AVAILABLE(ios(10), macosx(10.12), watchos(3), tvos(10)); #endif typedef NSURLSessionResponseDisposition (^AFURLSessionDataTaskDidReceiveResponseBlock)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLResponse *response); typedef void (^AFURLSessionDataTaskDidBecomeDownloadTaskBlock)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLSessionDownloadTask *downloadTask); typedef void (^AFURLSessionDataTaskDidReceiveDataBlock)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSData *data); typedef NSCachedURLResponse * (^AFURLSessionDataTaskWillCacheResponseBlock)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSCachedURLResponse *proposedResponse); typedef NSURL * (^AFURLSessionDownloadTaskDidFinishDownloadingBlock)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, NSURL *location); typedef void (^AFURLSessionDownloadTaskDidWriteDataBlock)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite); typedef void (^AFURLSessionDownloadTaskDidResumeBlock)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t fileOffset, int64_t expectedTotalBytes); typedef void (^AFURLSessionTaskProgressBlock)(NSProgress *); typedef void (^AFURLSessionTaskCompletionHandler)(NSURLResponse *response, id responseObject, NSError *error);
这一堆,我只是知道通知用到,回调block用到。完
************************************************************ 分割线来下,我需要你 第一个@interface 开始 *****************************************************************************
@interface AFURLSessionManagerTaskDelegate : NSObject <NSURLSessionTaskDelegate, NSURLSessionDataDelegate, NSURLSessionDownloadDelegate> - (instancetype)initWithTask:(NSURLSessionTask *)task; @property (nonatomic, weak) AFURLSessionManager *manager;//这个有用到 @property (nonatomic, strong) NSMutableData *mutableData; @property (nonatomic, strong) NSProgress *uploadProgress; @property (nonatomic, strong) NSProgress *downloadProgress; @property (nonatomic, copy) NSURL *downloadFileURL; #if AF_CAN_INCLUDE_SESSION_TASK_METRICS @property (nonatomic, strong) NSURLSessionTaskMetrics *sessionTaskMetrics AF_API_AVAILABLE(ios(10), macosx(10.12), watchos(3), tvos(10)); #endif @property (nonatomic, copy) AFURLSessionDownloadTaskDidFinishDownloadingBlock downloadTaskDidFinishDownloading; @property (nonatomic, copy) AFURLSessionTaskProgressBlock uploadProgressBlock; @property (nonatomic, copy) AFURLSessionTaskProgressBlock downloadProgressBlock; @property (nonatomic, copy) AFURLSessionTaskCompletionHandler completionHandler; @end
- (void)dealloc { //在监听属性的时候、可以用NSStringFromSelector(@selector(xxx))这种方式来自动提示。 http://www.cocoachina.com/articles/27509 [self.downloadProgress removeObserver:self forKeyPath:NSStringFromSelector(@selector(fractionCompleted))]; [self.uploadProgress removeObserver:self forKeyPath:NSStringFromSelector(@selector(fractionCompleted))]; }
不说了。
#pragma mark - NSURLSessionTaskDelegate -- 系统delegate - (void)URLSession:(__unused NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { NSLog(@"zlj--当前输出------------A1000 什么时候调用:%s",__FUNCTION__); error = objc_getAssociatedObject(task, AuthenticationChallengeErrorKey) ?: error;//不知道什么意思 __strong AFURLSessionManager *manager = self.manager; __block id responseObject = nil; /* (lldb) po userInfo { "com.alamofire.networking.task.complete.responseserializer" = "<AFJSONResponseSerializer: 0x600002ed1350>"; } */ NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; userInfo[AFNetworkingTaskDidCompleteResponseSerializerKey] = manager.responseSerializer;//eg, AFJSONResponseSerializer //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 AF_CAN_USE_AT_AVAILABLE && AF_CAN_INCLUDE_SESSION_TASK_METRICS if (@available(iOS 10, macOS 10.12, watchOS 3, tvOS 10, *)) { if (self.sessionTaskMetrics) { userInfo[AFNetworkingTaskDidCompleteSessionTaskMetrics] = self.sessionTaskMetrics; } } #endif 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; } /** 这个目的是返回网络请求结束之后返回数据, completionGroup:这个是.h中声明的属性,全局搜索没有找到赋值语句,猜测(如果程序员自己创建,就自己处理)这里是AF自己处理, 然后再发个通知出去,网络请求完成了,接下来该怎样就怎么。 */ 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]; }); }); }); } } #if AF_CAN_INCLUDE_SESSION_TASK_METRICS - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didFinishCollectingMetrics:(NSURLSessionTaskMetrics *)metrics AF_API_AVAILABLE(ios(10), macosx(10.12), watchos(3), tvos(10)) { self.sessionTaskMetrics = metrics; } #endif
kvo监听到了什么
#pragma mark - NSURLSessionDataDelegate - (void)URLSession:(__unused NSURLSession *)session dataTask:(__unused NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data { self.downloadProgress.totalUnitCount = dataTask.countOfBytesExpectedToReceive; self.downloadProgress.completedUnitCount = dataTask.countOfBytesReceived; [self.mutableData appendData:data]; } - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend{ self.uploadProgress.totalUnitCount = task.countOfBytesExpectedToSend; self.uploadProgress.completedUnitCount = task.countOfBytesSent; }
请求数据什么吧
#pragma mark - NSURLSessionDownloadDelegate - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{ self.downloadProgress.totalUnitCount = totalBytesExpectedToWrite; self.downloadProgress.completedUnitCount = totalBytesWritten; } - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes{ self.downloadProgress.totalUnitCount = expectedTotalBytes; self.downloadProgress.completedUnitCount = fileOffset; } - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location { self.downloadFileURL = nil; if (self.downloadTaskDidFinishDownloading) { self.downloadFileURL = self.downloadTaskDidFinishDownloading(session, downloadTask, location); if (self.downloadFileURL) { NSError *fileManagerError = nil; if (![[NSFileManager defaultManager] moveItemAtURL:location toURL:self.downloadFileURL error:&fileManagerError]) { [[NSNotificationCenter defaultCenter] postNotificationName:AFURLSessionDownloadTaskDidFailToMoveFileNotification object:downloadTask userInfo:fileManagerError.userInfo]; } else { [[NSNotificationCenter defaultCenter] postNotificationName:AFURLSessionDownloadTaskDidMoveFileSuccessfullyNotification object:downloadTask userInfo:nil]; } } } } @end
下载数据
************************************************************ 分割线来下,我需要你 第二个@interface 开始 *****************************************************************************
static inline void af_swizzleSelector(Class theClass, SEL originalSelector, SEL swizzledSelector) { Method originalMethod = class_getInstanceMethod(theClass, originalSelector); Method swizzledMethod = class_getInstanceMethod(theClass, swizzledSelector); method_exchangeImplementations(originalMethod, swizzledMethod); } static inline BOOL af_addMethod(Class theClass, SEL selector, Method method) { return class_addMethod(theClass, selector, method_getImplementation(method), method_getTypeEncoding(method)); } static NSString * const AFNSURLSessionTaskDidResumeNotification = @"com.alamofire.networking.nsurlsessiontask.resume"; static NSString * const AFNSURLSessionTaskDidSuspendNotification = @"com.alamofire.networking.nsurlsessiontask.suspend";
先做个准备
@implementation _AFURLSessionTaskSwizzling + (void)load { /** WARNING: Trouble Ahead https://github.com/AFNetworking/AFNetworking/pull/2702 */ if (NSClassFromString(@"NSURLSessionTask")) { /** iOS 7 and iOS 8 differ in NSURLSessionTask implementation, which makes the next bit of code a bit tricky. Many Unit Tests have been built to validate as much of this behavior has possible. Here is what we know: - NSURLSessionTasks are implemented with class clusters, meaning the class you request from the API isn't actually the type of class you will get back. - Simply referencing `[NSURLSessionTask class]` will not work. You need to ask an `NSURLSession` to actually create an object, and grab the class from there. - On iOS 7, `localDataTask` is a `__NSCFLocalDataTask`, which inherits from `__NSCFLocalSessionTask`, which inherits from `__NSCFURLSessionTask`. - On iOS 8, `localDataTask` is a `__NSCFLocalDataTask`, which inherits from `__NSCFLocalSessionTask`, which inherits from `NSURLSessionTask`. - On iOS 7, `__NSCFLocalSessionTask` and `__NSCFURLSessionTask` are the only two classes that have their own implementations of `resume` and `suspend`, and `__NSCFLocalSessionTask` DOES NOT CALL SUPER. This means both classes need to be swizzled. - On iOS 8, `NSURLSessionTask` is the only class that implements `resume` and `suspend`. This means this is the only class that needs to be swizzled. - Because `NSURLSessionTask` is not involved in the class hierarchy for every version of iOS, its easier to add the swizzled methods to a dummy class and manage them there. Some Assumptions: - No implementations of `resume` or `suspend` call super. If this were to change in a future version of iOS, we'd need to handle it. - No background task classes override `resume` or `suspend` The current solution: 1) Grab an instance of `__NSCFLocalDataTask` by asking an instance of `NSURLSession` for a data task. 2) Grab a pointer to the original implementation of `af_resume` 3) Check to see if the current class has an implementation of resume. If so, continue to step 4. 4) Grab the super class of the current class. 5) Grab a pointer for the current class to the current implementation of `resume`. 6) Grab a pointer for the super class to the current implementation of `resume`. 7) If the current class implementation of `resume` is not equal to the super class implementation of `resume` AND the current implementation of `resume` is not equal to the original implementation of `af_resume`, THEN swizzle the methods 8) Set the current class to the super class, and repeat steps 3-8 */ NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration]; NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration]; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wnonnull" NSURLSessionDataTask *localDataTask = [session dataTaskWithURL:nil]; #pragma clang diagnostic pop IMP originalAFResumeIMP = method_getImplementation(class_getInstanceMethod([self class], @selector(af_resume))); Class currentClass = [localDataTask class]; while (class_getInstanceMethod(currentClass, @selector(resume))) { Class superClass = [currentClass superclass]; IMP classResumeIMP = method_getImplementation(class_getInstanceMethod(currentClass, @selector(resume))); IMP superclassResumeIMP = method_getImplementation(class_getInstanceMethod(superClass, @selector(resume))); if (classResumeIMP != superclassResumeIMP && originalAFResumeIMP != classResumeIMP) { [self swizzleResumeAndSuspendMethodForClass:currentClass]; } currentClass = [currentClass superclass]; } [localDataTask cancel]; [session finishTasksAndInvalidate]; } } + (void)swizzleResumeAndSuspendMethodForClass:(Class)theClass { Method afResumeMethod = class_getInstanceMethod(self, @selector(af_resume)); Method afSuspendMethod = class_getInstanceMethod(self, @selector(af_suspend)); if (af_addMethod(theClass, @selector(af_resume), afResumeMethod)) { af_swizzleSelector(theClass, @selector(resume), @selector(af_resume)); } if (af_addMethod(theClass, @selector(af_suspend), afSuspendMethod)) { af_swizzleSelector(theClass, @selector(suspend), @selector(af_suspend)); } } - (NSURLSessionTaskState)state { NSAssert(NO, @"State method should never be called in the actual dummy class"); return NSURLSessionTaskStateCanceling; } - (void)af_resume { NSAssert([self respondsToSelector:@selector(state)], @"Does not respond to state"); NSURLSessionTaskState state = [self state]; [self af_resume]; if (state != NSURLSessionTaskStateRunning) { [[NSNotificationCenter defaultCenter] postNotificationName:AFNSURLSessionTaskDidResumeNotification object:self]; } } - (void)af_suspend { NSAssert([self respondsToSelector:@selector(state)], @"Does not respond to state"); NSURLSessionTaskState state = [self state]; [self af_suspend]; if (state != NSURLSessionTaskStateSuspended) { [[NSNotificationCenter defaultCenter] postNotificationName:AFNSURLSessionTaskDidSuspendNotification object:self]; } } @end
只是知道交换了实现方法,af_resume/resume ,af_suspend/suspend;
************************************************************ 分割线来下,我需要你 第三个@interface 开始 *****************************************************************************
@interface AFURLSessionManager () @property (readwrite, nonatomic, strong) NSURLSessionConfiguration *sessionConfiguration; @property (readwrite, nonatomic, strong) NSOperationQueue *operationQueue; @property (readwrite, nonatomic, strong) NSURLSession *session; @property (readwrite, nonatomic, strong) NSMutableDictionary *mutableTaskDelegatesKeyedByTaskIdentifier; @property (readonly, nonatomic, copy) NSString *taskDescriptionForSessionTasks; @property (readwrite, nonatomic, strong) NSLock *lock; @property (readwrite, nonatomic, copy) AFURLSessionDidBecomeInvalidBlock sessionDidBecomeInvalid; @property (readwrite, nonatomic, copy) AFURLSessionDidReceiveAuthenticationChallengeBlock sessionDidReceiveAuthenticationChallenge; @property (readwrite, nonatomic, copy) AFURLSessionDidFinishEventsForBackgroundURLSessionBlock didFinishEventsForBackgroundURLSession AF_API_UNAVAILABLE(macos); @property (readwrite, nonatomic, copy) AFURLSessionTaskWillPerformHTTPRedirectionBlock taskWillPerformHTTPRedirection; @property (readwrite, nonatomic, copy) AFURLSessionTaskAuthenticationChallengeBlock authenticationChallengeHandler; @property (readwrite, nonatomic, copy) AFURLSessionTaskNeedNewBodyStreamBlock taskNeedNewBodyStream; @property (readwrite, nonatomic, copy) AFURLSessionTaskDidSendBodyDataBlock taskDidSendBodyData; @property (readwrite, nonatomic, copy) AFURLSessionTaskDidCompleteBlock taskDidComplete; #if AF_CAN_INCLUDE_SESSION_TASK_METRICS @property (readwrite, nonatomic, copy) AFURLSessionTaskDidFinishCollectingMetricsBlock taskDidFinishCollectingMetrics AF_API_AVAILABLE(ios(10), macosx(10.12), watchos(3), tvos(10)); #endif @property (readwrite, nonatomic, copy) AFURLSessionDataTaskDidReceiveResponseBlock dataTaskDidReceiveResponse; @property (readwrite, nonatomic, copy) AFURLSessionDataTaskDidBecomeDownloadTaskBlock dataTaskDidBecomeDownloadTask; @property (readwrite, nonatomic, copy) AFURLSessionDataTaskDidReceiveDataBlock dataTaskDidReceiveData; @property (readwrite, nonatomic, copy) AFURLSessionDataTaskWillCacheResponseBlock dataTaskWillCacheResponse; @property (readwrite, nonatomic, copy) AFURLSessionDownloadTaskDidFinishDownloadingBlock downloadTaskDidFinishDownloading; @property (readwrite, nonatomic, copy) AFURLSessionDownloadTaskDidWriteDataBlock downloadTaskDidWriteData; @property (readwrite, nonatomic, copy) AFURLSessionDownloadTaskDidResumeBlock downloadTaskDidResume; @end
一通定义,block使用。
写不下去了,改天写!!