1. 程式人生 > >理解 Objective-C Runtime

理解 Objective-C Runtime

當人們初學 Cocoa/Objective-C 時,Objective-C Runtime 是被忽略的特性之一。原因是 Objective-C(這門語言)很容易在幾小時內就熟悉,新學 Cocoa 的人花費他們大部分的時間學習 Cocoa 框架和適應它是如何工作的。然而每個人至少應該知道一些 runtime 的工作細節,需要比知道編譯器會把 [target doMethodWith:var1];  轉換為 objc_msgSend(target,@selector(doMethodWith:),var1); 更深入一些。知道 Objective-C 正在做的會讓你更深入的理解 Objective-C 和你正在執行的 app。我認為 Mac/iPhone 的開發者不管你現在是什麼水平,都會有收穫的。

Objective-C Runtime 是開源的

Objective-C 是開源的,任何時候你都能從 http://opensource.apple.com. 獲取。事實上檢視 Objective-C 原始碼是我理解它是如何工作的第一種方式,在這個問題上要比讀蘋果的文件要好。你可以下載適合 Mac OS X 10.6.2 的 objc4-437.1.tar.gz。(譯註:最新objc4-551.1.tar.gz

動態 vs 靜態語言

Objective-C 是面相執行時的語言(runtime oriented language),就是說它會盡可能的把編譯和連結時要執行的邏輯延遲到執行時。這就給了你很大的靈活性,你可以按需要把訊息重定向給合適的物件,你甚 至可以交換方法的實現,等等(譯註:在 Objective-C 中呼叫一個物件的方法可以看成向一個物件傳送訊息, Method Swizzling 具體實現可以參看 

jrswizzle )。這就需要使用 runtime,runtime 可以做物件自省檢視他們正在做的和不能做的(don't respond to)並且合適的分發訊息(譯註:感興趣的同學可以檢視 NSObject 類的 – forwardingTargetForSelector: 和 – forwardInvocation: 方法。P.S. 不是 NSObject 協議! )。如果我們和 C 這樣的語言對比。在 C 裡,你從 main() 方法開始寫然後就是從上到下的寫邏輯了並按你寫程式碼的順序執行程式。一個 C 的結構體不能轉發函式執行請求到其他的目標上(other targets)。很可能你的程式是這樣的:

1 2 3 4 5 6 #include  int main(int argc, const char **argv[]) {         printf("Hello World!"); return 0; }

編譯器解析,優化然後把優化後的程式碼轉成彙編:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 .text .align 4,0x90 .globl _main _main: Leh_func_begin1: pushq %rbp Llabel1: movq %rsp, %rbp Llabel2: subq $16, %rsp Llabel3: movq %rsi, %rax movl %edi, %ecx  movl %ecx, -8(%rbp) movq %rax, -16(%rbp)  xorb %al, %al  leaq LC(%rip), %rcx  movq %rcx, %rdi  call _printf  movl $0, -4(%rbp)  movl -4(%rbp), %eax  addq $16, %rsp 

相關推薦

理解 Objective-C Runtime

當人們初學 Cocoa/Objective-C 時,Objective-C Runtime 是被忽略的特性之一。原因是 Objective-C(這門語言)很容易在幾小時內就熟悉,新學 Cocoa 的人花費他們大部分的時間學習 Cocoa 框架和適應它是如何工作的。然而

Objective-C runtime機制(4)——深入理解Category

在平日程式設計中或閱讀第三方程式碼時,category可以說是無處不在。category也可以說是OC作為一門動態語言的一大特色。category為我們動態擴充套件類的功能提供了可能,或者我們也可以把一個龐大的類進行功能分解,按照category進行組織。 關於category的使用

深入理解Objective-C:Category

fix 忽略 DDU 相關 情況 內存布局 先生 們的 ntc https://tech.meituan.com/DiveIntoCategory.html 摘要 無論一個類設計的多麽完美,在未來的需求演進中,都有可能會碰到一些無法預測的情況。那怎麽擴展已有的類呢?一般而言

Objective-C Runtime 文檔翻譯(一)—Runtime版本和平臺

註意 mar 包含 mark 編譯 href enc 文檔翻譯 需要 前言 ? 在不同的平臺,有不同版本的OC runtime。 ? 舊的和現在的版本 ? 有兩個版本的OC runtime——“舊版”和“現在版”。現在版就是OC-2.0並包含了許多新特性。舊版本的ru

Objective-C runtime機制

Objective-C runtime機制 先來看看怎麼理解發送訊息的含義: 曾經覺得Objc特別方便上手,面對著 Cocoa 中大量 API,只知道簡單的查文件和呼叫。還記得初學 Objective-C 時把[receiver message]當成簡單的方法呼叫,而無視了“傳送訊息

Objective-C runtime機制(7)——SideTables, SideTable, weak_table, weak_entry_t

在runtime中,有四個資料結構非常重要,分別是SideTables,SideTable,weak_table_t和weak_entry_t。它們和物件的引用計數,以及weak引用相關。 關係 先說一下這四個資料結構的關係。 在runtime記憶體空間中,SideTables是

Objective-C runtime機制(6)——weak引用的底層實現原理

前言 提起弱引用,大家都知道它的作用: (1)不會新增引用計數 (2)當所引用的物件釋放後,引用者的指標自動置為nil 那麼,圍繞它背後的實現,是怎麼樣的呢?在許多公司面試時,都會問到這個問題。那麼,今天就帶大家一起分析一下weak引用是怎麼實現的,希望能夠搞清楚每一個細節。 S

Objective-C runtime機制(5)——iOS 記憶體管理

概述 當我們建立一個物件時: SWHunter *hunter = [[SWHunter alloc] init]; 上面這行程式碼在棧上建立了hunter指標,並在堆上建立了一個SWHunter物件。目前,iOS並不支援在棧上建立物件。 iOS 記憶體分割槽 iOS

Objective-C runtime機制(3)——method swizzling

方法替換,又稱為method swizzling,是一個比較著名的runtime黑魔法。網上有很多的實現,我們這裡直接講最正規的實現方式以及其背後的原理。 Method Swizzling 在進行方法替換前,我們要考慮兩種情況: 要替換的方法在target class

Objective-C runtime機制(2)——訊息機制

當我們用中括號[]呼叫OC函式的時候,實際上會進入訊息傳送和訊息轉發流程: 訊息傳送(Messaging),runtime系統會根據SEL查詢對用的IMP,查詢到,則呼叫函式指標進行方法呼叫;若查詢不到,則進入訊息轉發流程,如果訊息轉發失敗,則程式crash並記錄日誌。

Objective-C runtime機制(1)——基本資料結構:objc_object & objc_class

前言 從本篇文章開始,就進入runtime的正篇。 什麼是runtime? OC是一門動態語言,與C++這種靜態語言不同,靜態語言的各種資料結構在編譯期已經決定了,不能夠被修改。而動態語言卻可以使我們在程式執行期,動態的修改一個類的結構,如修改方法實現,繫結例項變數等。

Objective-C runtime機制(前傳2)——Mach-O格式和runtime

在前傳1中,我們分析瞭解了XNU核心所支援的二進位制檔案格式Mach-O。同時還留了一個小尾巴,就是Mach-O檔案中和Objective-C以及runtime相關的Segment section。今天,就來了解一下它們。 OC之源起 我們知道,程式的入口點在iOS中被稱之為ma

Objective-C runtime機制(前傳)——Mach-O格式

Mach-O Mach-O是Mach Object檔案格式的縮寫。它是用於可執行檔案,動態庫,目的碼的檔案格式。作為a.out格式的替代,Mach-O格式提供了更強的擴充套件性,以及更快的符號表資訊訪問速度。 Mach-O格式為大部分基於Mach核心的作業系統所使用的,包括NeX

ios學習路線—Objective-C(Runtime訊息機制)

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

Objective-C Runtime 執行時之五:協議與分類

Objective-C中的分類允許我們通過給一個類新增方法來擴充它(但是通過category不能新增新的例項變數),並且我們不需要訪問類中的程式碼就可以做到。 Objective-C中的協議是普遍存在的介面定義方式,即在一個類中通過@protocol定義介面,在另外

Objective-C Runtime 執行時之六:拾遺

前面幾篇基本介紹了runtime中的大部分功能,包括對類與物件、成員變數與屬性、方法與訊息、分類與協議的處理。runtime大部分的功能都是圍繞這幾點來實現的。 本章的內容並不算重點,主要針對前文中對Objective-C Runtime Reference內容遺漏

Objective C Runtime

Objective-C Objective-C 擴充套件了 C 語言,並加入了面向物件特性和 Smalltalk 式的訊息傳遞機制。而這個擴充套件的核心是一個用 C 和 編譯語言 寫的 Runtime 庫。它是 Objective-C 面向物件和動態機制的基石。 Objectiv

Objective-C Runtime 執行時之一:類與物件

Objective-C語言是一門動態語言,它將很多靜態語言在編譯和連結時期做的事放到了執行時來處理。這種動態語言的優勢在於:我們寫程式碼時更具靈活性,如我們可以把訊息轉發給我們想要的物件,或者隨意交換一個方法的實現等。 這種特性意味著Objective-C不僅需要一

Objective-C Runtime 執行時之二:成員變數與屬性

在前面一篇文章中,我們介紹了Runtime中與類和物件相關的內容,從這章開始,我們將討論類實現細節相關的內容,主要包括類中成員變數,屬性,方法,協議與分類的實現。 本章的主要內容將聚集在Runtime對成員變數與屬性的處理。在討論之前,我們先介紹一個重要的概念:型別

Objective-C Runtime 執行時之三:方法與訊息

前面我們討論了Runtime中對類和物件的處理,及對成員變數與屬性的處理。這一章,我們就要開始討論Runtime中最有意思的一部分:訊息處理機制。我們將詳細討論訊息的傳送及訊息的轉發。不過在討論訊息之前,我們先來了解一下與方法相關的一些內容。 基礎資料型別 SEL