5

我想知道谁会在objective-c中调用main方法?

我知道 UIApplicationMain(nil,nil,nil,NSStringFromClass[Appdelgate class]) 方法是从 main() 方法调用,然后从 appdelegate didFinishLaunchingWithOptions() 方法继续处理.....

而且我也知道 java 中的 main() 方法由 JVM 调用,并且进程正在从 main() 方法进行。

像那样,我想知道谁会在 Objective-c 中调用 main()。

感谢帮助

4

4 回答 4

3

找出答案的简单方法是插入断点main()并查看:

调用栈

所以从技术上讲,这个问题的答案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()被调用。startMac 版本的程序集start并不完全相同,但非常接近。所以这是一个很好的猜测,它start是编译器根据目标平台为你生成的,start也是操作系统在启动程序时寻找的入口点。

于 2012-07-18T15:10:07.013 回答
2

我相信它是由 Obj-C 运行时库中的汇编例程调用的,与 C 中相同,但使用 C 运行时库

检查这个:https ://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html

于 2012-07-18T14:38:37.250 回答
2

在大多数系统中,操作系统具有负责将可执行程序加载到内存中的特殊功能。它们分配所需的内存并将文件中的信息加载到该空间中。在某些情况下,他们甚至可能对代码进行特殊修改,以便它在加载它的特定内存空间中工作。

将程序加载到内存后,操作系统将控制权传递给程序文件代码段的开头。代码段的开头通常有一个小例程,它执行一些必要的操作,如初始化堆栈和内存堆。当这些事情完成后,它会将控制权交给 main() 函数。

于 2012-07-18T14:45:25.537 回答
1

由于 Objective-C 是 C 的派生词,因此许多内部结构是相似的(这就是为什么您可以将 C\C++ 代码与 Objective-C 混合使用)。因此,当两者都编译成可执行文件时,它们在相似的系统上工作。这也是为什么 Objective-C 由 gcc 或 Clang 编译的原因。

考虑到这一点,编译时会发生什么?您的所有 C 代码都被转换为汇编\机器代码(因为汇编只是机器代码的助记符版本)。汇编比Java低;CPU 只是运行它并按顺序执行每个单独的指令。C 语言中的main()函数是编译器“知道”指令从哪里开始的地方。完成所有声明后,该main()函数将跳转到一条名为“ jmp”的指令。

那么当你在 Xcode 中编译并启动时会发生什么?首先,gcc/Clang 将代码转换成汇编\机器码。其次,Xcode 将二进制文件加载到内存中。第三,Darwin(OS X 或 iOS,或与此相关的任何操作系统)认识到这是一个可执行的内存区域,并从指令集的顶部开始并贯穿每条指令。

为了回答您的问题,该main()功能由 CPU 启动。这与 Java 不同,后者具有在 JVM 中“模拟”的独立于平台的指令集。

这个问题有一个很好的答案,它解释了main()函数如何被翻译成汇编代码。

于 2012-07-18T14:42:19.013 回答