深入研究Runtime(1) - 前言

Christi8914 8年前發布 | 6K 次閱讀 Runtime iOS開發 移動開發 IOS

首先我們先看看文檔如何描述Runtime的,如下:

The Objective-C language defers as many decisions as it can from compile time and link time to runtime. Whenever possible, it does things dynamically. This means that the language requires not just a compiler, but also a runtime system to execute the compiled code. The runtime system acts as a kind of operating system for the Objective-C language; it’s what makes the language work.

大概的意思就是:OC語言盡可能的動態地處理事情,將決定盡可能地從編譯時鏈接時推遲到運行時。意味著,OC語言不僅僅需要一個編譯器,還需要一個運行時系統執行已經編譯好的代碼。

下面將從兩個方面學習Runtime:

  1. OC 運行時系統是如何工作的?
  2. 如何使用運行時系統?

補充:
其實發展到現在,Runtime技術已經發展了兩個版本,一個OC2.0以后的modern版本,和之前legacy版本。
這兩個版本的主要區別是:

  1. 類中實例變量的排序改變后,是否需要重新編譯該類的子類,在legacy版本是必須的,而modern則不必須。
  2. modern版本支持@property屬性

支持的平臺:
modern:iPhone系統 && 64-bit OS X v10.5后的系統
legacy:32bit OS X 系統

與運行時系統交互的的方式( 詳細的交互在后面章節再說明 )

分為三個不同的層次:

  1. Objective-C 源碼
  2. NSObject 的方法
  3. 直接調用 runtime 函數

Objective-C 源碼

當編譯器編譯OC的類和方法時,會生成數據結構函數調用實現語言的動態特性。

  • 數據結構在哪里獲取到信息?

    1. 類和分類定義 / 協議聲明
    2. 類對象和協議對象
    3. 方法選擇器( method selector )
    4. 實例變量模板
    5. 源碼提取到的其它信息
  • 函數調用

    1. 最主要的運行時函數就是發送消息,由源碼的消息表達式調用。例如:[dog run]這個表達式會調用運行時的發送消息函數

NSObject 的方法

其中一些方法可以簡單查詢運行時系統獲取信息。這些方法可以讓對象實現自省

+(Class)class // 獲得類對象
-(BOOL)isKindOfClass:(Class)aClass // 是否是指定類或者其子類
-(BOOL)isMemberOfClass:(Class)aClass // 是否是指定類
-(BOOL)respondsToSelector:(SEL)aSelector // 是否實現指定方法或者其父類實現
+(BOOL)conformsToProtocol:(Protocol *)aProtocol // 類是否實現了指定協議
-(IMP)methodForSelector:(SEL)aSelector // 定位和返回接收者方法實現的地址,所以可以像函數調用一樣

Cocoa中大多數的類都繼承于NSObject( 特例:NSProxy ),所以大多數類都擁有上述自省方法。在NSObject中,大多數方法只是簡單地實現,例如:

+(NSString *)description // 默認返回類名和地址

詳細實現功能還需自己重寫。

直接調用 runtime 函數

運行時系統是一個動態共享庫,/usr/include/objc 目錄下提供了一套函數數據結構的公共接口。

補充:

  • 什么是selector?
    一個對象選擇一個方法執行的名稱,又或者是源碼編譯后,取代這個名稱的唯一標識

  • selector的作用:
    在OC源碼階段,selector一般當前是方法的唯一標識。而在運行時,selector就作為一個動態函數指針,根據給的方法名指向相對應類中的方法的具體實現

  • 獲得一個selector:
    編譯好的類型是:SEL,有兩種途徑可以獲得

    1. 編譯時,使用@selector指令:

      SEL aSelector = @selector(methodName);

    2. 運行時,使用NSSelectorFromString函數

      SEL aSelector = NSSelectorFromString(@"methodName");

  • 調用selector:
    使用performSelector:方法

    SEL aSelector = @selector(run); // 運行時會自動指向 對應類 的方法實現
    [aDog performSelector:aSelector];
    [anAthlete performSelector:aSelector];

為了防止篇章過長,后面內容分篇章記錄


 

文/老譚是誰(簡書作者)
來自:http://www.jianshu.com/p/2cb150a6caba

 本文由用戶 Christi8914 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!