Runtime 的方法交換 IMP

2021-09-24 06:35:31 字數 1986 閱讀 9572

前言

runtime 又叫執行時,是一套底層的 c 語言 api,其為 ios 內部的核心之一,我們平時編寫的 oc **,底層都是基於它來實現的。

強大之處

objc 在三種層面上與 runtime 系統進行互動:

runtime 有個東西是"方法欺騙"(imp 方法的交換). 表面上呼叫的是方法a,但內部呼叫的是方法b

nsstring * str = @"李";

nsurl * url = [nsurl urlwithstring:str];

nslog(@"1----%@",url);

列印:2017-09-14 17:45:41.777 runtime[4402:1147114] 1----(null)

複製**

這裡出現nil 是因為 字串包含中文,導致轉成url時不識別. 可以utf-8 轉碼處理

nsstring* string2 = [str stringbyaddingpercentescapesusingencoding:nsutf8stringencoding];

複製**

但是每次出現乙個url 你都要這樣處理,顯然是很麻煩的. 就算你寫在類別裡面處理,使用的地方你要匯入標頭檔案,使用新加的類別方法.新專案還ok.

但是你要改寫別人的**你會瘋掉的.

下面要介紹使用runtime來處理這個事情 不過還是要新建乙個nsurl類別的

引用#import 

runtime的標頭檔案

複製**

#import "nsurl+url.h"

#import

@implementation nsurl (url)

複製**

新增類別方法來做處理+(instancetype)strurl:(nsstring *)str

+(instancetype)strurl:(nsstring *)str 

return url;

}複製**

我們希望在外面還呼叫下面這個系統方法,但是希望內部走+(instancetype)strurl:(nsstring *)str處理

[nsurl urlwithstring:str];

複製**

ok,其實乙個類被記憶體裝載時,會呼叫乙個方法: +(void)load 在這裡做它們兩個的方法交換處理

// 這個類被裝載的時候呼叫 進入記憶體的時候呼叫

+(void)load

複製**

這時候兩個方法已經交換完了,但是你自己新加的類方法:+(instancetype)strurl:(nsstring *)str內部實現還是有 :nsurl * url = [nsurl urlwithstring:str];這樣會造成死迴圈.你應該這樣把這個方法(nsurl * url = [nsurl urlwithstring:str];)也替換掉

#import "nsurl+url.h"

#import

@implementation nsurl (url)

// 這個類被裝載的時候呼叫 進入記憶體的時候呼叫

+(void)load

+(instancetype)strurl:(nsstring *)str

return url;

}@end

複製**

這裡已經ok了

外面依然是使用系統的方法:[nsurl urlwithstring:str]

但內部是走的自己新加的方法:+(instancetype)strurl:(nsstring *)str

執行時(runtime) 方法交換

1 建立乙個 person 類,並定義兩個方法 study 和 run,分別實現 import person.h implementation person void study void run end 2 正常呼叫方法 int main int argc,const char argv 執行程式...

Swift 中使用runtime交換方法實現

在swift的viewcontroller中寫了如下 func first func second override func viewdidload 執行結果 第乙個方法。發現沒有達到我們預期的目的,同樣的 用oc實現如下 void first void second void viewdidlo...

runtime 動態新增方法

動態新增方法 動態新增就運用到懶載入 開發場景 如果乙個類方法很多,載入類到記憶體的時候也比較耗費資源,需要給每個方法生成乙個對映表 這個詞我也不懂 可以使用動態給某個類新增方法。person p person alloc init perform selector 即為動態新增方法 p perfo...