您的位置:首页 > 移动开发 > Objective-C

Block初探

2016-04-14 15:47 555 查看

何为 Block

block是能够截获自动变量(局部变量)的匿名函数

Block 语法

完整形式的 Block 语法与一般的 C 语言函数定义相比,仅有两点不同

没有函数名

带有 ‘^’

语法定义

^ 返回值类型(void 可省略) 参数列表(void 可省略) 表达式

^int (int count) {
return count + 1;
}

^{printf("Blocks\n");} //void省略


Block 类型变量

C 语言可以将定义的函数的地址赋值给函数指针类型变量

int func(int count)
{
return count + 1;
}

int (*funcptr) (int) = &func;


同样地,Block 语法下,可将 Block 语法生成的值赋值给 Block 类型的变量中。

int (^blk) (int);


和 C 语言相比,仅仅是把 ‘*’ 变成 ‘^’ ,可作以下用途:

自动变量

函数参数

静态变量

静态全局变量

全局变量

//赋值
int (^blk1) (int) = ^int (int count) {
return count + 1;
};

int (^blk2) (int) = blk1;
blk1 = blk2;

//参数传递
void func (int (^blk) (int))
{
//do something
}


在函数参数和返回值中使用 Block类型的变量时,记述的方式十分复杂。这时使用 typedef 来简化

typedef int (^someBlk)(int);

/* 原来的记述方式
void func (int (^blk) (int))
*/
void func (someBlk blk)
{
//这样调用
blk(10);
}


Block 类型变量可以像 C 语言中的其他类型变量一样使用。

截获自动变量值

一开始我有说明Block是带有“自动变量的匿名函数”,那什么是带有自动变量值呢?

举个例子

int main()
{
int dmy = 256;
int val = 10;
const char *fmt =“val = %d \n”;
void(^blk)(void)= ^{printf(fmt,val);};
val = 2;
fmt =“These values were changed val = %d \n”;
blk();
return 0;
}


执行结果会是 val = 10

执行结果并不是改写后的值,而是执行Block语法时的自动变量的瞬间值。该Block语法在执行时,字符串指标“cal = %d \n”被赋值到自动变量fmt中,int值被赋值到val中,因此这边值被保存(即被截获),而在执行时被使用。

这就是自动变量值的截获。

__block说明符

实际上,截获变量只能保存Block语法的瞬间值,保存后就不能改写该值。

这时,若想在Block语法的表达式中将值赋给Block语法外声明的自动变量,需要在该自动变量上附加__block。

使用附有block说明符的自动变量可在Block中赋值,该变量称为block变量。

int main()
{
int dmy = 256;
__block int val = 10;
__block char *fmt =“val = %d \n”;
void(^blk)(void)= ^{printf(fmt,val);};
val = 2;
fmt =“These values were changed val = %d \n”;
blk();
return 0;
}


执行结果会是 These values were changed val = 2

原文参考:http://www.jianshu.com/p/1c8b8a584910
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  block object-c