当执行下面问题代码:
NSURL *url = [NSURL URLWithString:@"https://www.baidu.com/中文字符串"];
NSLog(@"url:%@",url);
打印日志:显示null
2019-09-03 18:09:59.087098+0800 RACUse[1761:2943445] url:(null)
所以当我们对类似系统方法进行拦截或者优化时, 往往使用运行时的方法交换
1.创建一个URL的扩展类NSURL+KKURL.h / NSURL+KKURL.m
- 导入runtime
2.在+ (void) load { }方法 中添加代码
@implementation NSURL (KKURL)
+ (void)load {
//系统url方法
Method urlM = class_getClassMethod([self class], @selector(URLWithString:));
//新的url方法
Method urlNewM = class_getClassMethod([self class], @selector(KKURLWithString:));
//交换方法
method_exchangeImplementations(urlM, urlNewM);
}
+ (nullable instancetype)KKURLWithString:(NSString *)URLString {
NSURL *url = [self KKURLWithString:URLString];
if (url) {
return url;
} else {
NSLog(@"无效url");
return [NSURL new];
}
}
我们注意到KKURLWithString:里面为啥是:
NSURL *url = [self KKURLWithString:URLString];
而不是:
NSURL *url = [self URLWithString:URLString];//会导致循环
其实现在URLWithString:URLString
调用的是KKURLWithString:URLString
方法,
而KKURLWithString:URLString
调用的是URLWithString:URLString
方法,
所以下面代码会导致死循环:
+ (nullable instancetype)KKURLWithString:(NSString *)URLString {
NSURL *url = [self URLWithString:URLString];
...
}
相反,下面方法正常:
+ (nullable instancetype)KKURLWithString:(NSString *)URLString {
NSURL *url = [self KKURLWithString:URLString];
...
}