block可能是我在学习objective-c语法中遇到的第一个puzzle的地方。确实,这个语法takes some getting use to.
block实际是一种闭包,它是oc中对闭包的实现。闭包是什么?清楚地记得这个是我去年在参加鹅厂的实习笔试的时候的一个大题,记得没错是第二个大题。anyway,跑题了。。。
我是通过c中的函数指针的方式去理解block的。毕竟两个概念写起来太像了。例如一个ptr函数指针的声明:
int (*ptr)(int*, float);
相应的block可以这么声明:
int (^bptr)(int*, float);
block需要使用符号^声明,^读作caret,看几个block的例子:
int main(int args, char *argv[]) {
<span style="white-space:pre"> </span>@autoreleasepool {
<span style="white-space:pre"> </span>void ^(showMessage)(void) = ^(void) {
<span style="white-space:pre"> </span>NSLog("hehe");
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>showMessage();
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>return 0;
}
block可以访问block外部的成员,拿到block定义的时候成员的值,注意下面showMessge()输出3,而不是7:
int main(int args, char *argv[]) {
<span> </span>@autoreleasepool {
<span style="white-space:pre"> </span>int val = 3;
<span> </span>void ^(showMessage)(void) = ^(void) {
<span> </span>NSLog(@"val =%i", val);
<span> </span>}
<span style="white-space:pre"> </span>val = 7;
<span style="white-space:pre"> </span>showMessage();
<span> </span>}
<span> </span>return 0;
}
通常情况下,编译器是不允许在block内部修改block外部的成员值。在block内部看来,外部的成员对它而已是read-only的。
block访问外部变量: