1.2.2 变量查询和唤醒程序
_MyHomePageState中并没有widget属性,那widget.title是哪里来的?setState是否真的每次在调用时都会执行build方法?调试断点如下:
程序会先运行到第二个断点,因为程序先执行到这里。如果想要对变量进行查询,可以在变量区查看,也可以通过变量表达式操作。
在变量区可以看到this对象中有一个名为_widget的私有成员变量,它是MyHomePage类型。现在进行简单的推理,_MyHomePageState并未定义_widget属性,那必然是其父类中的成员,_MyHomePageState继承自State类,所以widget必定在State类中:
这里调用的是widget而非_widget,这时就要去State源码里一探究竟了(代码如下)。可见源码中返回一个T泛型的对象_widget。这里get关键字也是Dart的一颗语法糖,相当于Java的getXXX,无论是写法还是用法都比Java简洁优雅。
---->[State]---- abstract class State<T extends StatefulWidget> extends Diagnosticable{ T get widget => _widget; ... }
到这里似乎清晰许多,State本身接收一个StatefulWidget泛型类,这里_widget便是该类型对象。通过State#widget的方法获取组件对象,因此可拿到其中定义的属性值,如title。
但还有个问题:State是一个抽象类,并没有对_widget属性进行赋值,那_widget赋值的时机在哪呢?这里先埋一个伏笔,这个问题将在Day 8中进行解答。当然你也可以尝试用Debug自己找一找,锻炼一下。
使用键可以将程序唤醒,击碎当前断点。当程序运行到下一断点时,会再次停下。注意,由于默认开发模式有热加载,build会被执行两次,所以点一下不动是正常的,其实是已经走了一圈,又停在这里而已。这时会发现界面已经显示出来了。
接下来会发现Debug面板如下,不懂Debug的人可能认为已经结束了。但是断点还在那看守着呢,点击加号按钮时会让程序在setState里的断点处停下,点击唤醒按钮,程序会跳到build里的断点,这说明setState方法确实会触发build方法。