runtime實戰(二)動態修改方法
阿新 • • 發佈:2018-11-01
在上篇博文上大家瞭解了什麼是runtime,並瞭解OC的訊息傳送機制,下面就進入runtime實戰,解決實際問題:動態修改方法
一、我們經常使用的NSURL方法如下:
NSURL *url = [NSURL URLWithString:@"www.xxx.華為"];
當字串中有中文時,url為空,在使用時會加一個判空操作。如果使用地方很多,在每處都加上判空,會使程式碼相當繁瑣。
二、有朋友想新增一個類目,自己宣告一個方法:
NSURL+url.h:
@interface NSURL (url)
+ (instancetype)SH_URLWithString:(NSString *)string;
@end
NSURL+url.m:
@implementation NSURL (url)
+ (instancetype)SH_URLWithString:(NSString *)string
{
NSURL *url = [NSURL URLWithString:string];
if (url == nil) {
// Handle the nil exception;
NSLog(@"the urlString is nil");
}
return string;
}
@end
當然,這個方法是可行性,我們每次使用這個自定義方法便可實現效果,但是對於大的專案,在每個檔案中匯入標頭檔案,並且每次都記得使用該方法,顯然有些繁瑣。
三、接下來我們就使用runtime來動態的修改系統方法:
NSObject方法:
@interface NSObject <NSObject> {
Class isa OBJC_ISA_AVAILABILITY;
}
+ (void)load;
該方法會在工程編譯時被呼叫,在main函式之前,我們想要改系統方法時機,就是在這個方法被呼叫時。
#import "NSURL+url.h"
#import <objc/message.h>
@implementation NSURL (url)
// 當這個檔案被載入進來時被呼叫,在main函式之前,檔案被編譯時,程式啟動之前;
+ (void)load
{
// 1.獲取系統URLWithString方法
Method URLWithStr = class_getClassMethod([NSURL class], @selector(URLWithString:));
// 2.獲取自定義的SHURLWithString方法
Method SHURLWithStr = class_getClassMethod([NSURL class], @selector(SH_URLWithString:));
// runtime方法之一:交換兩個方法的實現。
method_exchangeImplementations(URLWithStr, SHURLWithStr);
}
// 如果修改了系統的方法,請添加註釋
+ (instancetype)SH_URLWithString:(NSString *)string
{
NSURL *url = [NSURL SH_URLWithString:string];
if (url == nil) {
// Handle the nil exception;
NSLog(@"the urlString is nil");
}
return nil;
}
@end
load中的三個runtime方法分別獲取到了系統的URLWithString方法,和自定義的SH_URLWithString方法,然後交換了這兩個方法的實現,
所以以後我們使用系統的URLWithString方法。
NSURL *url = [NSURL URLWithString:@”www.xxx.華為”];
其實內部已經進行了判空操作。
我的GitHub程式碼地址:https://github.com/lvshaohua/SH_Runtime