谁将在目标c中调用Main方法

时间:2012-07-18 14:32:40

标签: iphone

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

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

我也知道java中的main()方法是由JVM调用的,而进程是从main()方法继续进行的。

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

感谢您的帮助

4 个答案:

答案 0 :(得分: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是操作系统在启动程序时查找的入口点。

答案 1 :(得分:2)

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

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

答案 2 :(得分:2)

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

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

答案 3 :(得分:1)

由于Objective-C是C的衍生物,因此很多内部结构都是相似的(这就是为什么你可以将C \ C ++代码与Objective-C混合))。因此,当两者都编译成可执行文件时,它们会在类似的系统中运行。这也是为什么Objective-C是由gcc或Clang编译的。

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

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

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

This问题有一个很好的答案,可以解释main()函数如何转换为汇编代码。