这是我参与「第四届青训营 」笔记创作活动的第7天
今天,在上青训营课程「闭包与objective-c block」时的一个例题引起了我的好奇
可以看到,在左边的例子中,由于闭包捕获的value值为1,所以运行结果为1和2,然而在右边的例子中,闭包捕获的self.name明明是1,但是运行结果确实两个2。这其中的原因是闭包捕获的其实是self变量,而不是self.name变量,于是在实际运行的时候,self.name已经变为2,所以闭包内输出的结果也是2。
而这立刻让我联想到了c++的虚函数,最终运行的函数是动态编译的。于是我立刻用objective-c尝试了一下代码:
果然!objective-c里面的类方法运行的方式跟c++的虚函数是一样的。
然后我用c++ lambda表达式也写了这样类似的代码,结果和objective-c是一样的。
然而,由于runtime机制的存在,objective-c是一种动态语言。如果说,objective-c是动态语言,因此捕获self并不奇怪,但是c++可是静态语言啊,为什么也是捕获this指针呢?
仔细想想后发现这样做非常合理!因为编译器没法确定你会不会在lambda表达式前加上"this->age = 3"的这样的赋值语句,假如不加的话,如果要直接捕获this->age而不是this,编译器必须在执行了test()的语句往上文找,这样就太麻烦了而且可能出现各种作用域的嵌套。就像常成员只能在出现在常成员函数里,常对象只能调用常函数。因此在闭包和lambda表达式里捕获的就是self/this指针而不是变量值。