iOS開發日記17-runtime基礎篇,ios17-runtime

來源:互聯網
上載者:User

iOS開發日記17-runtime基礎篇,ios17-runtime

今天博主有一個runtime基礎的需求,遇到了一些困痛點,在此和大家分享,希望能夠共同進步.

Objective-C runtime是一個執行階段程式庫,主要是由C語言和組合語言寫成,為C語言添加物件導向的能力而創造了Objective-C。這意味著它可以載入類資訊,進行方法派發以及方法轉寄等等。Objective-C 運行時最重要的就是為Objective-C語言的物件導向特性的實現提供了所有的基礎支撐.

 

那麼,runtime具體究竟是什麼呢?相信各位看官百度了很多文章後,發現十篇有九篇都看不懂,這時因為有很多基礎的東西我們並不瞭解,今天博主就和大家分享一下,runtime基礎篇

我們寫的代碼在程式運行過程中都會被轉化成runtime的C代碼執行,例如[xxxxxx doSomething];會被轉化成objc_msgSend(xxxxxx, @selector(doSomething));

OC中一切都被設計成了對象,我們都知道一個類被初始化成一個執行個體,這個執行個體是一個對象。實際上一個類本質上也是一個對象,在runtime中用結構體表示。

 

相關的定義:

/// 描述類中的一個方法typedef struct objc_method *Method;/// 執行個體變數typedef struct objc_ivar *Ivar;/// 類別Categorytypedef struct objc_category *Category;/// 類中聲明的屬性typedef struct objc_property *objc_property_t;

類在runtime中的表示

//類在runtime中的表示struct objc_class {  Class isa;//指標,顧名思義,表示是一個什麼,  //執行個體的isa指向類對象,類對象的isa指向元類#if !__OBJC2__  Class super_class;  //指向父類  const char *name;  //類名  long version;  long info;  long instance_size  struct objc_ivar_list *ivars //成員變數列表  struct objc_method_list **methodLists; //方法列表  struct objc_cache *cache;//緩衝  //一種最佳化,調用過的方法存入緩衝列表,下次調用先找緩衝  struct objc_protocol_list *protocols //協議列表  #endif} OBJC2_UNAVAILABLE;/* Use `Class` instead of `struct objc_class *` */

相信很多看官看到這裡的時候,就已經有想關螢幕的衝動了,下面給大家分享一下isa指標和meta class(元類)

每個對象都會有一個它所屬的類。這是物件導向的基本概念,但是在OC中,這對所有資料結構有效。任何資料結構,只要在恰當的位置具有一個指標指向一個class,那麼,它都可以被認為是一個對象。
在OC中,一個對象所屬於哪個類,是由它的isa指標指向的。這個isa指標指向這個對象所屬的class。

isa:是一個Class 類型的指標. 每個執行個體對象有個isa的指標,他指向對象的類,而Class裡也有個isa的指標, 指向meteClass(元類)。元類儲存了類方法的列表。當類方法被調用時,先會從本身尋找類方法的實現,如果沒有,元類會向他父類尋找該方法。同時注意的是:元類(meteClass)也是類,它也是對象。元類也有isa指標,它的isa指標最終指向的是一個根元類(root meteClass).根元類的isa指標指向本身,這樣形成了一個封閉的內迴圈

一個OC的類其實也是一個對象,意思就是你可以向一個類發送訊息。
NSStringEncoding defaultStringEncoding = [NSString defaultStringEncoding];
在這個例子中,defaultStringEncoding 被發送給了NSString類。因為每一個OC的類本身也是一個對象。也就是說Class的資料結構必然也是以isa指標開始的在二進位層級上與objc_object是完全相容的。然後一個類結構的下一個欄位一定是一個指向super class的指標(或者指向nil,對於基類而言)。
一個類如何定義有很多方法,依賴於你的執行階段程式庫版本,但是不管哪種方法,他們都是以一個isa作為第一個欄位,接著是superclass欄位

為了可以調用類方法,這個類的isa指標必須指向一個包含這些類方法的類結構體。
這樣就引出了meta-class的概念:meta-class是一個類對象的類。
簡單解釋下:
       當你向一個對象發送訊息時,runtime會在這個對象所屬的那個類的方法列表中尋找。
       當你向一個類發送訊息時,runtime會在這個類的meta-class的方法列表中尋找。

meta-class之所以重要,是因為它儲存著一個類的所有類方法。每個類都會有一個單獨的meta-class,因為每個類的類方法基本不可能完全相同
meta-class,就像Class一樣,也是一個對象。你依舊可以向它發送訊息調用函數,自然的,meta-class也會有一個isa指標指向其所屬類。所有的meta-class使用基類的meta-class作為他們的所屬類。具體而言,任何NSObject繼承體系下的meta-class都使用NSObject的meta-class作為自己所屬的類。

根據這個規則,所有的meta-class使用基類的meta-class作為它們的類,而基類的meta-class也是屬於它自己,也就是說基類的meta-class的isa指標指向它自己。
就像一個類使用super_class指標指向自己的父類一樣,meta-class的super_class會指向類的super_class的meta-class。一直追溯到基類的meta-class,它的super_class會指向基類自身

這樣一來,整個繼承體系中的執行個體、類和meta-class都派生自繼承體系中的基類。對於NSObject繼承體系來說,NSObject的執行個體方法對體系中所有的執行個體、類和meta-class都是有效;NSObject的類方法對於體系中所有的類和meta-class都是有效
meta-class是類對象的類,每個類都有自己單獨的meta-class。所有的類對象並不會屬於同一個meta-class。

meta-class要保證類對象具有繼承體系中基類的所有執行個體和類方法,以及繼承體系中的所有中間類方法。對於所有NSObject繼承體系下的類,NSObject的執行個體方法和協議方法對他們和他們meta-class的對象都要有效。
所有的meta-class使用基類的meta-class作為自己的基類,對於頂層基類的meta-class也是一樣,只是它指向自己而已

runtime的應用:


1.動態建立一個類(比如KVO的底層實現)


 2.動態地為某個類添加屬性\方法, 修改屬性值\方法


3.遍曆一個類的所有成員變數(屬性)\所有方法


實質上,以上的是通過相關方法來擷取對象或者類的isa指標來實現的。


相關函數


1.  增加


增加函數:class_addMethod


增加執行個體變數:class_addIvar


增加屬性:@dynamic標籤,或者class_addMethod,因為屬性其實就是由getter和setter函數組成


增加Protocol:class_addProtocol (說實話我真不知道動態增加一個protocol有什麼用,-_-!!)


2.  擷取


擷取函數列表及每個函數的資訊(函數指標、函數名等等):class_getClassMethod method_getName ...


擷取屬性列表及每個屬性的資訊:class_copyPropertyList property_getName


擷取類本身的資訊,如類名等:class_getName class_getInstanceSize


擷取變數列表及變數資訊:class_copyIvarList


擷取變數的值


3.    替換


將執行個體替換成另一個類:object_setClass


替換類方法的定義:class_replaceMethod


4.其他常用方法:


交換兩個方法的實現:method_exchangeImplementations.


設定一個方法的實現:method_setImplementation.

 
還有幾篇文章可以增加各位對runtime的理解
http://quotation.github.io/objc/2015/05/21/objc-runtime-ivar-access.html
http://www.jianshu.com/p/425a39d43d16?utm_campaign=maleskine&utm_content=note&utm_medium=writer_share&utm_source=weibo
http://mp.weixin.qq.com/s?__biz=MjM5NTIyNTUyMQ==&mid=208927760&idx=1&sn=30b9caecba709553e463d719668454ae&scene=2&from=timeline&isappinstalled=0#rd

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.