iOS開發中runtime常用的幾種方法示例總結

2022-09-21 09:03:12 字數 3900 閱讀 6115

前言

objective-c runtime是乙個實現objective-c語言的c庫。它是一門編譯型語言、也是一門動態型的語言(這裡強調下oc是靜態型別語言),之前沒接觸runtime的時候也不覺著它有多重要,接觸之後才發現其實runtime挺強大的。就拿我們在ios開發中所使用的oc程式語言來講,oc之所以能夠做到即是編譯型語言,又能做到動態語言,就是得益於runtime的機制。

最近公司專案中用了一些 runtime 相關的知識, 初看時有些蒙, 雖然用的並不多, 但還是想著系統的把 runtime 相關的常用方法整理一下, 自己以後用著方便, 也希望對看到的朋友有所幫助.

一、runtime 簡介

runtime 簡稱執行時,是系統在執行的時候的一些機制,其中最主程式設計客棧要的是訊息機制。它是一套比較底層的純 c 語言 api, 屬於乙個 c 語言庫,包含了很多底層的 c 語言 api。我們平時編寫的 oc **,在程式執行過程時,其實最終都是轉成了 runtime 的 c 語言**。如下所示:

// oc**:

[person coding];

//執行時 runtime 會將它轉化成 c 語言的**:

objc_msgsend(person, @selector(coding));

二、相關函式

// 遍歷某個類所有的成員變數

class_copyivarlist

// 遍歷某個類所有的方法

class_copymethodlist

// 程式設計客棧獲取指定名稱的成員變數

class_getinstancevariable

// 獲取成員變數名

ivar_getname

// 獲取成員變數型別編碼

ivar_gettypeencoding

// 獲取某個物件成員變數的值

object_getivar

// 設定某個物件成員變數的值

object_setivar

// 給物件傳送訊息

objc_msgsend

三、相關應用

以上八種用法用**都實現了, 文末會貼出**位址.

runtime

四、**實現

要使用runtime,要先引入標頭檔案#import

4.1 更改屬性值

用 runtime 修改乙個物件的屬性值

unsigned int count = 0;

// 動態獲取類中的所有屬性(包括私有)

ivar *ivar = class_copyivarlist(_person.class, &count);

// 遍歷屬性找到對應字段

for (int i = 0; i < count; i ++)

}4.2 動態新增屬性

用 runtime 為乙個類新增屬性, ios 分類裡一般會這樣用, 我們建立乙個分類, nsobject+nnaddattribute.h, 並新增以下**:

- (void)setname:(nsstring *)name

- (nsstring *)name

這樣只要引用 nsobject+nnaddattribute.h, 用 nsobject 建立的物件就會有乙個 name 屬性, 我們可以直接這樣寫:

nsobject *person = [nsobject new];

person.name = @"以夢為馬";

4.3 動態新增方法

person 類中沒有 coding 方法,我們用 runtime 給 person 類新增了乙個名字叫 coding 的方法,最終再呼叫coding方法做出相應. 下面**的幾個引數需要注意一下:

- (void)buttonclick:(uibutton *)sender else }

// 編寫 codingoc 的實現

void codingoc(id self,sel _cmd)

4.4 交換方法的實現

某個類有兩個方法, 比如 person 類有兩個方法, coding 方法與 eating 方法, 我們用 runtime 交換一下這兩個方法, 就會出現這樣的情況, 當我們呼叫 coding 的時候, 執行的是 eating, 當我們呼叫 eating 的時候, 執行的是 coding, 如下面的動態效果圖.

method orimethod = class_getinstancemethod(_person.class, @selector(coding));

method curmethod = class_getin @selector(eating));

method_exchangeimplementations(orimethod, curmethod);

交換方法的實現

4.5 攔截並替換方法

這個功能和上面的其實有些類似, 攔截並替換方法可以攔截並替換同乙個類的, 也可以在兩個類之間進行, 我這裡用了兩個不同的類, 下面是簡單的**實現.

_person = [nnperson new];

_library = [nnlibrary new];

self.testlabeltext = [_library librarymethod];

method orimethod = class_getinstancemethod(_person.class, @selector(changemethod));

method curmethod = class_getinstancemethod(_library.class, @selector(librarymethod));

method_exchangeimplementations(orimethod, curmethod);

4.6 在方法上增加額外功能

這個使用場景還是挺多的, 比如我們需要記錄 app 中某乙個按鈕的點選次數, 這個時候我們便可以利用 runtime 來實現這個功能. 我這裡寫了個 uibutton 的子類, 然後在 + (void)load 中用 runtime 給它增加了乙個功能, 核心**及實現效果圖如下:

+ (void)load else

});}

在方法上增加額外功能

4.7 歸檔解檔

當我們使用 nscoding 進行歸檔及解檔時, 如果不用 runtime, 那麼不管模型裡面有多少屬性, 我們都需要對其實現一遍 encodeobject 和 decodeobjectforkey 方法, 如果模型裡面有 10000 個屬性, 那麼我們就需要寫 10000 句encodeobject 和 decodeobjectforkey 方法, 這個時候用 runtime, 便可以充分體驗其好處(以下只是核心**, 具體**請見 demo).

- (void)encodewithcoder:(nscoder *)acoder

free(ivars);

}- (instancetype)initwithcoder:(nscoder *)adecoder

} return self;

}4.8 字典轉模型

字典轉模型我們通常用的都是第三方, mjextension, yymodel 等, 但也有必要了解一下其實現方式: 遍歷模型中的所有屬性,根據模型的屬性名,去字典中查詢對應的 key,取出對應的值,給模型的屬性賦值。

/** 字典轉模型 **/

+ (instancetype)modelwithdict:(nsdictionary *)dict

} if ([value iskindofclass:[nsarray class]])

// 把模型陣列賦值給value

value = arrm;

}} // kvc 字典轉模型

if (value)

} return objc;

}上面的所有**都可以在這裡**: runtime 練習: nnruntimetest

總結本文標題: ios開發中runtime常用的幾種方法示例總結

本文位址:

iOS開發中runtime的使用

事實證明 1.傳送訊息 implementation viewcontroller void viewdidload end implementation uiimage image 載入分類到記憶體的時候呼叫 void load 注意 不能在分類中重寫系統方法imagenamed,因為會把系統的功...

iOS開發 runtime機制

runtime簡稱執行時。就是系統在執行的時候的一些機制,其中最主要的是訊息機制。對於c語言,函式的呼叫在編譯的時候會決定呼叫哪個函式 c語言的函式呼叫請看這裡 編譯完成之後直接順序執行,無任何二義性。oc的函式呼叫成為訊息傳送。屬於動態呼叫過程。在編譯的時候並不能決定真正呼叫哪個函式 事實證明,在...

iOS開發中Runtime的實際應用

runtime是objective c的乙個固有特性,及在編譯階段並不能確定真正呼叫的函式名,函式的呼叫在執行時才得到確認。所以我們可以看到,oc在編譯階段沒有報錯的情況下,會在執行過程中出現閃退和崩潰的錯誤,而c語言在編譯過程中就會報錯。ios的錯誤處理 編譯未出報錯,執行卻閃退 動態呼叫特性 c...