當我們使用到NSURL的時候 ,有的時候會遇到中文的情況,這個時候,再去訪問網絡請求,就會造成系統識別到的url是nil的情況。
NSURL *url = [NSURL URLWithString:@"www.baidu.com/中文"];
當然我們可以使用轉碼的方式,去解決這個問題。
但是,每個地方都要這么做嗎?當然不是了,這樣子會很麻煩的
1.首先,我們創建一個類別
@interface NSURL (url)
+(instancetype)HZ_URLWithStr:(NSString *)str;
@end
//這個地方 就處理識別到的URL為空的情況
+(instancetype)HZ_URLWithStr:(NSString *)str
{
NSURL *url = [NSURL URLWithString:str];
if (url == nil) {
NSLog(@"url = nil");
}
return url;
}
2.然后我們就可以使用了
導入頭文件
#import "NSURL+url.h"
NSURL *urlStr = [NSURL HZ_URLWithStr:@"www.baidu.com/中文"];
但是這樣子,我們仍然需要在每個地方都導入我們寫的類別才能使用。當然,導入pch文件也是可以的。
3.但是我們的主題是使用runtime輕松解決。
上代碼
是在我們定義的類別NSURL+url 的.m文件中直接進行使用
導入runtime
#import <objc/message.h>
因為message里面包含的有runtime
#include <objc/objc.h>
#include <objc/runtime.h>
然后就是重點了
+(void)load
{
Method URLWithString = class_getClassMethod([NSURL class], @selector(URLWithString:));
Method HZ_URLWithStr = class_getClassMethod([NSURL class], @selector(HZ_URLWithStr:));
method_exchangeImplementations(URLWithString, HZ_URLWithStr);
}
load 方法會在啟動時加載,我們的這個文件,也不需要在任何地方導入。
class_getClassMethod
class_getClassMethod 獲取類方法
method_exchangeImplementations
method_exchangeImplementations 交換方法
這樣子就完了嗎?
當然不是。
+(instancetype)HZ_URLWithStr:(NSString *)str;中我們使用的是
+(instancetype)HZ_URLWithStr:(NSString *)str
{
NSURL *url = [NSURL URLWithString:str];
if (url == nil) {
NSLog(@"url = nil");
}
return url;
}
我們已經將系統的方法和自定義的方法進行了交換,在使用的時候
依然是使用系統的方法,如下:
NSURL *url = [NSURL URLWithString:@"www.baidu.com/中文"];
那么問題來了,我們使用系統的方法,此時會調用我們自定義的方法(已經進行了交換),那么在我們自己的方法中,我們使用到的又是系統的方法(交換過了),那這樣子不就造成了循環引用了。這樣子會造成crash的。所以我們需要進行如下的操作,看著很別扭的。
+(instancetype)HZ_URLWithStr:(NSString *)str
{
NSURL *url = [NSURL HZ_URLWithStr:str];
if (url == nil) {
NSLog(@"url = nil");
}
return url;
}
這樣子,在里面處理相關的邏輯,就能在不導入任何文件的情況下,輕松的攔截出現的問題。
NSURL *url = [NSURL URLWithString:@"www.baidu.com/中文"];
當然了,在自定義這個方法的時候 一定要備注好,不能給自己的小伙伴和以后的自己留坑啊。
--------------------下面是完整的代碼----------------
.h文件
@interface NSURL (url)
+(instancetype)HZ_URLWithStr:(NSString *)str;
@end
.m文件
#import "NSURL+url.h"
#import <objc/message.h>
@implementation NSURL (url)
+(void)load
{
Method URLWithString = class_getClassMethod([NSURL class], @selector(URLWithString:));
Method HZ_URLWithStr = class_getClassMethod([NSURL class], @selector(HZ_URLWithStr:));
method_exchangeImplementations(URLWithString, HZ_URLWithStr);
}
+(instancetype)HZ_URLWithStr:(NSString *)str
{
NSURL *url = [NSURL HZ_URLWithStr:str];
if (url == nil) {
NSLog(@"url = nil");
}
return url;
}
@end
使用到的類
NSURL *url = [NSURL URLWithString:@"www.baidu.com/中文"];
至此,我們的文章算是完成了。