runtime實戰(二)動態修改方法

在上篇博文上大家瞭解了什麼是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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章