1

我一直在尝试调整 NSURLSession 类的 dataTaskWithURL 方法。这就是我尝试过的

+ (void)swizzleDataTaskWithRequest {
Class class = [self class];

SEL originalSelector = @selector(dataTaskWithRequest:completionHandler:);
SEL swizzledSelector = @selector(my_dataTaskWithRequest:completionHandler:);

Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);

BOOL didAddMethod = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod),method_getTypeEncoding(swizzledMethod));

if (didAddMethod) {
    class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod),method_getTypeEncoding(originalMethod));
} else {
    method_exchangeImplementations(originalMethod, swizzledMethod);
}
}


- (NSURLSessionDataTask *)my_dataTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSData * __nullable data, NSURLResponse * __nullable response, NSError * __nullable error))completionHandler{


NSLog(@"***************************");

return [self my_dataTaskWithURL:url completionHandler:completionHandler];
}

而这个 my_dataTaskWithURL 我想传递自己的完成处理程序,但我不知道如何创建它

提前致谢 !!

4

2 回答 2

1

在决定使用 class_replaceMethod 技术之前 - 您应该阅读method_setImplementation与 c 实现一起使用的内容。

method_setImplementation返回原始实现,然后您可以直接存储和调用它。相比之下,当您使用exchangeImplementations此原始实现时,只能通过您的 swizzling Method typedef 获得。这将导致与 Self 一起传递到方法调用中的隐藏选择器 _cmd 成为您的 swizzling 方法的选择器。当用户的方法依赖于正确的 _cmd(选择器)参数时,这可能会导致问题。

这是一个很好的资源:

https://blog.newrelic.com/2014/04/16/right-way-to-swizzle/

于 2016-07-22T15:59:33.893 回答
0

如果您只实现 NSURLSession 的调配,那么这将与 Alamofire 和其他第三方 SDK 一起使用。您需要使用 URLProtocol 进行基础调配。以下是要点链接,对每个人都非常有帮助。

https://gist.github.com/nil-biribiri/ceead941d5b482207cb1b872c5d76a60

于 2019-06-22T05:44:45.790 回答