2012-07-18 46 views
5

我想知道誰將調用objective-c中的主要方法?誰將調用目標c中的主要方法

我知道UIApplicationMain(零,零,零,NSStringFromClass [Appdelgate類])方法從main()方法調用,然後過程從的appdelegate didFinishLaunchingWithOptions繼續()方法.....

而我也知道java中的main()方法被JVM調用,並且進程正在從main()方法進行。

就像那樣,我想知道誰會在objective-c中調用main()。

感謝您的幫助

回答

3

最簡單的方法,找出是要堅持一個斷點main()看一看:

call stack

所以從技術上來說,這個問題的答案是main()是從一種叫start調用。您沒有獲得start的源代碼,但是如果需要的話,您可以在調試器中查看彙編代碼。這個版本是從模擬器內置代碼:

0x1c30: pushl $0 
0x1c32: movl %esp, %ebp 
0x1c34: andl $-16, %esp 
0x1c37: subl $16, %esp 
0x1c3a: movl 4(%ebp), %ebx 
0x1c3d: movl %ebx, (%esp) 
0x1c40: leal 8(%ebp), %ecx 
0x1c43: movl %ecx, 4(%esp) 
0x1c47: addl $1, %ebx 
0x1c4a: shll $2, %ebx 
0x1c4d: addl %ecx, %ebx 
0x1c4f: movl %ebx, 8(%esp) 
0x1c53: movl (%ebx), %eax 
0x1c55: addl $4, %ebx 
0x1c58: testl %eax, %eax 
0x1c5a: jne 0x00001c53    ; start + 35 
0x1c5c: movl %ebx, 12(%esp) 
0x1c60: calll 0x00001c70    ; main at main.m:9 
0x1c65: movl %eax, (%esp) 
0x1c68: calll 0x00002376    ; exit 
0x1c6d: hlt  
0x1c6e: nop  
0x1c6f: nop 

如果您創建一個MacOS X的命令行程序,把一個斷點main(),你會發現,main()start在桌面上叫了。 Mac版start的裝配不完全相同,但非常接近。因此,編譯器基於目標平臺爲您生成start是一個很好的猜測,並且start是操作系統啓動程序時的入口點。

+0

非常感謝你 – 2012-07-20 07:29:18

1

由於Objective- C是C的衍生物,大部分內部結構都是相似的(這就是爲什麼你可以將C \ C++代碼與Objective-C混合))。因此,當它們都編譯成可執行文件時,它們都可以使用類似的系統。這也是爲什麼Objective-C由gcc或Clang編譯的原因。

考慮到這一點,編譯時會發生什麼?所有的C代碼都被轉換成Assembly \ machine code(因爲Assembly只是機器代碼的助記符版本)。程序集比Java低; CPU只是運行它並按順序執行每個單獨的指令。 C語言中的main()函數是編譯器'知道'指令從何處開始的地方。完成所有聲明後,將使用名爲'jmp'的指令跳轉main()函數。

那麼當你在Xcode中編譯並啓動時會發生什麼?首先,gcc/Clang將代碼轉換成Assembly \ machine code。其次,Xcode將二進制文件加載到內存中。第三,達爾文(OS X或iOS或任何操作系統)認識到這是一個可執行的內存區域,從指令集的頂部開始並貫穿每條指令。

要回答你的問題,main()函數由CPU啓動。這與Java不同,Java具有獨立於平臺的指令集,可在JVM中「模擬」。

This問題有一個很好的答案,它解釋瞭如何將main()函數轉換成彙編代碼。

2

在大多數系統中,OS具有負責將可執行程序加載到內存中的特殊功能。他們分配所需的內存並將文件中的信息加載到該空間中。在某些情況下,他們甚至可能會對代碼進行特殊修改,以使其在加載的特定內存空間中工作。

將程序加載到內存後,OS將控制權交給程序文件代碼段的開頭。代碼段的開始通常有一個小例程,它執行一些必要的操作,如初始化堆棧和內存堆。當這些事情完成後,它將控制傳遞給main()函數。