Objective-C Runtime方法替換引發的死循環

當執行下面問題代碼:

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

  1. 導入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];
...
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容