Swift程序入口深度分析

Swift程序入口深度分析

id="iframeu2217703_0" src="http://pos.baidu.com/hcum?rdid=2217703&dc=2&di=u2217703&dri=0&dis=0&dai=4&ps=450x124&dcb=BAIDU_SSP_define&dtm=HTML_POST&dvi=0.0&dci=-1&dpt=none&tsr=0&tpr=1477148520965&ti=Swift%E7%A8%8B%E5%BA%8F%E5%85%A5%E5%8F%A3%E6%B7%B1%E5%BA%A6%E5%88%86%E6%9E%90_IOS_%E7%AC%AC%E4%B8%83%E5%9F%8E%E5%B8%82&ari=2&dbv=0&drs=1&pcs=1229x667&pss=1229x675&cfv=0&cpl=1&chi=2&cce=true&cec=UTF-8&tlm=1477148523&rw=667&ltu=http%3A%2F%2Fwww.th7.cn%2FProgram%2FIOS%2F201411%2F322846.shtml&ltr=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DYNCbeLWVF7ObjaDEX9X0nNNrwrIC22yuX7a1hHcVXfjHrcNI8No7lN29IWQ7TLAExfpYBoRR12go6F60vV-gyq%26wd%3D%26eqid%3Da8160266000440f000000006580b7f62&ecd=1&psr=1440x900&par=1440x817&pis=-1x-1&ccd=24&cja=true&cmi=8&col=zh-cn&cdo=-1&tcn=1477148523&qn=a7f107a256d4c0ab&tt=1477148520937.2478.2593.2595" width="200" height="200" align="center,center" vspace="0" hspace="0" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" allowtransparency="true" style="display: block; border-width: 0px; vertical-align: bottom; margin: 0px;">
1.swift为什么不需要main


在c/c++及其它语言中都有一个main函数,程序从main作为起点,开始执行程序,如下:
int main(int argc, const char * argv[]) {    printf("Hello, World!/n");    return 0;}

main函数实际上是一个特殊的函数,为了能找到程序入口,大多楼语言都约定main()函数作为入口。那么为什么在Swift中没有这样的一个函数呢?先看一下官方的解释

Code written at global scope is used as the entry point for the program, so you don’t need a main function. 
大体意思是,在main.swift中的代码是在全局作用域下,这些代码直接作为整个项目的入口,所以这里并不需要main函数。


2.C与Swift的入口对比
在ios/osx系统中,C/Objective-c项目也有main()函数的约定,在项目入口main()代码块打断点




从上图可以看出在执行程序前,先调用了**start()**方法,而后再执行约定的**main()**方法,这种我们能够很好理解,那么在swift下情况如何呢?




从上图可以看出Swift的执行顺序是start()->main()->top_level_code(),相对于C语言项目,多出来top_level_code(),在main.swift中的(非声明)代码会直接作为top_level_code()代码执行。此处要注意在Swift语言本身并不需要入口函数,程序入口是指定为main.swift中的非声明代码。在具体编译环节,ios/osx的入口均采用约定的main()函数,为了兼容以前的入口方法,将Swift语言程序在编译环节处理成隐式入口函数top_level_code(),再由main()调用。


3.代码top_level_code()
在官方解释
> Code written at global scope is used as the entry point for the program, so you don’t need a main function. 

提及到全局作用域,main.swift中的声明(如变量、常量、类、结构体、枚举)类代码,会作为全局作用域,在程序的任何都方都可以使用。而其中的非声明(赋值、for循环、if语句等)代码,会作为top_level_code()中代码来执行。这里注意,声明类代码与非声明类代码的作用域并不相同。声明类的作用域是全局作用域,而非声明类代码为top_level_code()作用域。

这里特别注意,只有在main.swift中的代码才可以作为top_level_code来执行。
而在其它文件中,是不能直接在文件中含有非声明类的语句,只能含有声明类的代码。

4.偷天换日,替换隐式入口函数top_level_code()
在编译环节,编译器将main.swift非声明代码作为top_level_code()来执行,为了能够让程序执行我们的入口函数,而不是main.swift代码,需要声明并实现这个特殊的top_level_code()函数
void top_level_code();
下一步如何让编译程序指定我们写的top_level_code(),这里需要注意

* main.swift文件不能删除,如果删除程序直接不能编译通过
* 为了能让编译程序认可我们写的top_level_code()函数,我们需要在main.swift文件中主动使用一次top_level_code()
这里的使用是指两种情况:
1. 在main.swift直调用我们写的top_level_code()函数
2. 在main.swift的声明类、结构体等的方法中调用top_level_code()函数

注意

这两种方法都会导致main.swift中的所有代码不再执行。此处在main.swift加入上述代码的作用就是让编译器改调用我们写的top_level_code函数

具体可以直接下载项目来研究
为了测试里面用到了
1. Swift项目调用C及Objective-c代码的办法
2. Objective-c代码调用Swift代码
3. 类的声明


5.Swift打印入口参数

在C言语中的**main**函数中,有两个参数
* argc:  命令行中字符串数
* argv:  指向字符串的指针数组
 这两个参数在Swift中被声明为全局变量,分别为
 
 * C_ARGC 
 * C_ARGV
 
 我们也可以在Swift中将入口参数打印出来,注意C中类型与Swift的类型转换
//将C语言int型转换为Swift中的Intlet cout = Int(C_ARGC)println("all->/(cout)")let end = cout - 1for index in 0...(end) {    //获取指定C语言字符串,并将C字符串转换为Swift的String类型    let str = String.fromCString(C_ARGV[index])    println("/(str)")}

点击运行完成后->将项目Products目录入的文件直接拖入终端中->在后面添加空格"aaa"空格"bbb",类似下面的格式
/Users/mac/Library/Developer/Xcode/DerivedData/ILHelloWorld-fvywvzypiomcffbiuxdxwwdaeued/Build/Products/Debug/ILHelloWorld "aaa" "bbb"
打印运行结果如下:
all->3Optional("/Users/mac/Library/Developer/Xcode/DerivedData/ILHelloWorld-fvywvzypiomcffbiuxdxwwdaeued/Build/Products/Debug/ILHelloWorld")Optional("aaa")Optional("bbb")

其中第一个参数为默认的程序路径,第二个及第三个参数为我们在上面输入的**aaa**及**bbb**,加起来共3个参数
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值