當執行下面問題代碼:
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];//會導致循環
image.png
其實現在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];
...
}