Swift中函数未提前定义却可调用的运行机制及代码执行流程问询
Swift中函数调用在定义前不报错的原因及代码运行流程
一、为什么viewDidLoad调用upDateUI不会报错?
这是因为Swift对类的处理是先整体解析,再执行代码,和你理解的“从上到下逐行执行”不是一回事:
- 编译阶段,Swift会先扫描整个
ViewController类的所有成员(包括所有属性、方法),不管这些成员写在类里的哪个位置,都会先把它们的信息记录下来,生成类的方法表和属性列表。 - 等到运行时执行
viewDidLoad里的upDateUI()调用时,编译器早就知道这个方法存在了,所以不会报“未定义”的错误。 - 你觉得的“从上到下执行”是运行时代码的执行顺序,而类成员的可见性是在编译阶段就确定的,和代码书写顺序无关。
二、这段代码的完整运行步骤
- 类定义解析阶段:程序编译时,Swift会完整扫描
ViewController类的所有内容,包括IBOutlet控件引用、quiz数组、questionNumber变量、viewDidLoad、answerButton、upDateUI方法,把这些成员的信息全部录入类的结构中。 - ViewController实例化:程序启动后,系统创建
ViewController的实例,初始化所有属性:questionNumber被设置为初始值0;quiz数组被初始化,存储3个问题字符串;- 界面加载完成后,IBOutlet会自动连接到storyboard里对应的UI控件(questionLabel、progressBar等)。
- 执行viewDidLoad方法:
- 先调用
super.viewDidLoad(),完成UIViewController父类的初始化工作; - 调用
upDateUI()方法:此时questionNumber是0,所以把quiz[0]的文本("Four + Two is equal to Six")赋值给questionLabel,界面上就显示第一个问题了。
- 先调用
- 用户交互阶段:当用户点击true或false按钮时:
- 触发
answerButton方法,questionNumber自增1(从0变成1,再点击变成2); - 再次调用
upDateUI(),把quiz数组中对应下标的问题文本赋值给questionLabel,实现问题切换。
- 触发
内容的提问来源于stack exchange,提问作者JuliaWang
相关产品推荐
相关产品推荐

