麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發設計 > 正文

Objective-C總Runtime的那點事兒(一)消息機制【轉】

2019-11-14 17:56:12
字體:
來源:轉載
供稿:網友

RunTime簡稱運行時。就是系統在運行的時候的一些機制,其中最主要的是消息機制。對于C語言,函數的調用在編譯的時候會決定調用哪個函數( C語言的函數調用請看這里 )。編譯完成之后直接順序執行,無任何二義性。OC的函數調用成為消息發送。屬于動態調用過程。在編譯的時候并不能決定真正調用哪個函數(事實證明,在編 譯階段,OC可以調用任何函數,即使這個函數并未實現,只要申明過就不會報錯。而C語言在編譯階段就會報錯)。只有在真正運行的時候才會根據函數的名稱找 到對應的函數來調用。

那OC是怎么實現動態調用的呢?下面我們來看看OC通過發送消息來達到動態調用的秘密。假如在OC中寫了這樣的一個代碼:

1
[obj makeText];

其中obj是一個對象,makeText是一個函數名稱。對于這樣一個簡單的調用。在編譯時RunTime會將上述代碼轉化成

1
objc_msgSend(obj,@selector(makeText));

首先我們來看看obj這個對象,iOS中的obj都繼承于NSObject。

1
2
3
@interface NSObject <nsobject> {
    Class isa  OBJC_ISA_AVAILABILITY;
}</nsobject>

在NSObjcet中存在一個Class的isa指針。然后我們看看Class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
typedef struct objc_class *Class;
struct objc_class {
  Class isa; // 指向metaclass
   
  Class super_class ; // 指向其父類
  const char *name ; // 類名
  long version ; // 類的版本信息,初始化默認為0,可以通過runtime函數class_setVersion和class_getVersion進行修改、讀取
  long info; // 一些標識信息,如CLS_CLASS (0x1L) 表示該類為普通 class ,其中包含對象方法和成員變量;CLS_META (0x2L) 表示該類為 metaclass,其中包含類方法;
  long instance_size ; // 該類的實例變量大小(包括從父類繼承下來的實例變量);
  struct objc_ivar_list *ivars; // 用于存儲每個成員變量的地址
  struct objc_method_list **methodLists ; // 與 info 的一些標志位有關,如CLS_CLASS (0x1L),則存儲對象方法,如CLS_META (0x2L),則存儲類方法;
  struct objc_cache *cache; // 指向最近使用的方法的指針,用于提升效率;
  struct objc_PRotocol_list *protocols; // 存儲該類遵守的協議
    }

 

我們可以看到,對于一個Class類中,存在很多東西,下面我來一一解釋一下:

Class isa:指向metaclass,也就是靜態的Class。一般一個Obj對象中的isa會指向普通的Class,這個Class中存儲普通成員變量和對 象方法(“-”開頭的方法),普通Class中的isa指針指向靜態Class,靜態Class中存儲static類型成員變量和類方法(“+”開頭的方 法)。

Class super_class:指向父類,如果這個類是根類,則為NULL。

下面一張圖片很好的描述了類和對象的繼承關系:

iuqQFnm.png

注意:所有metaclass中isa指針都指向跟metaclass。而跟metaclass則指向自身。Root metaclass是通過繼承Root class產生的。與root class結構體成員一致,也就是前面提到的結構。不同的是Root metaclass的isa指針指向自身。

Class類中其他的成員這里就先不做過多解釋了,下面我們來看看:

@selector (makeText):這是一個SEL方法選擇器。SEL其主要作用是快速的通過方法名字(makeText)查找到對應方法的函數指針,然后調用其函 數。SEL其本身是一個Int類型的一個地址,地址中存放著方法的名字。對于一個類中。每一個方法對應著一個SEL。所以iOS類中不能存在2個名稱相同 的方法,即使參數類型不同,因為SEL是根據方法名字生成的,相同的方法名稱只能對應一個SEL。

下面我們就來看看具體消息發送之后是怎么來動態查找對應的方法的。

首先,編譯器將代碼[obj makeText];轉化為objc_msgSend(obj, @selector (makeText));,在objc_msgSend函數中。首先通過obj的isa指針找到obj對應的class。在Class中先去cache中 通過SEL查找對應函數method(猜測cache中method列表是以SEL為key通過hash表來存儲的,這樣能提高函數查找速度),若 cache中未找到。再去methodList中查找,若methodlist中未找到,則取superClass中查找。若能找到,則將method加 入到cache中,以方便下次查找,并通過method中的函數指針跳轉到對應的函數中去執行。


上一篇:IOS圖片全屏預覽

下一篇:iOS內存管理

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 亚洲无线看 | 99精品国产成人一区二区 | 中文字幕 欧美 日韩 | 国产精品久久久久久久久久10秀 | 中文字幕线观看 | 久久凹凸| 羞羞网站| 青热久思思 | 天天干导航 | 看国产精品 | 钻石午夜影院 | 被啪羞羞视频在线观看 | 蜜桃视频观看麻豆 | 成人毛片100免费观看 | 成熟女人特级毛片www免费 | 久国产精品视频 | 黄色淫片 | 久久国产精品久久久久 | 美女久久久久 | 国产精品爱久久久久久久 | 72pao成人国产永久免费视频 | 亚洲精品aa | 精品国产一区三区 | 亚洲精品欧美在线 | 国产精品久久久久久久久久 | 免费的毛片 | av性色全交蜜桃成熟时 | 日韩视频在线观看免费 | 日韩美香港a一级毛片免费 欧美一级淫片007 | 国产一级在线观看视频 | 久久中文字幕在线观看 | 日韩欧美高清一区 | 成人毛片视频在线观看 | 国产精品久久久久久久久久东京 | 亚洲黑人在线观看 | 国产羞羞视频免费在线观看 | 国产亚洲精品久久久久久久久久 | 看毛片电影 | 中文字幕网在线 | 久久精品一区二区三区四区五区 | 国产一级一级 |