Block 1:什么是Blocks
来源:互联网 发布:java hadoop 开发 编辑:程序博客网 时间:2024/05/17 04:54
Blocks是C语言的扩充功能。可以用一句话来表示Blocks的扩充功能:带有局部变量的匿名函数。
顾名思义,所谓匿名函数就是不带名称的函数。C语言的标准不允许存在这样的函数。例如以下源代码:
int func(int count);
它声明了名称为func的函数。下面的源代码中为了调用该函数,必须使用该函数的名称func。
int result = func(10);
如果像下面这样,使用函数指针来代替直接调用函数,那么似乎不用知道函数名也能够使用该函数。
int result = (*funcptr)(10);
但其实使用函数指针也仍然需要知道函数名称。像以下源代码这样,在赋值给函数指针时,若不使用想赋值的函数的名称,就无法取得该函数的地址。
int (*funcptr)(int) = &func;int result = (*funcptr)(10);
而通过Blocks,源代码中就能够使用匿名函数,即不带名称的函数。对于程序员而言,命名就是工作的本质,函数名、变量名、方法名、属性名、类名和框架名等必须具备。而能够编写不带名称的函数对程序员来说相当具有吸引力。
到这样,我们知道了“带有局部变量的匿名函数”中“匿名函数”的概念。那么“带有局部变量”究竟是什么呢?
首先回顾一下在C语言的函数中可能使用的变量。
- 局部变量
- 函数的参数
- 静态变量(静态局部变量)
- 静态全局变量
- 全局变量
其中,在函数的多次调用之间能够传递值的变量有:
- 静态变量(静态局部变量)
- 静态全局变量
- 全局变量
虽然这些变量的作用域不同,但在整个程序当中,一个变量总保持在一个内存区域。因此虽然多次调用函数,但该变量值总能保持不变,在任何时候以任何状态调用,使用的都是同样的变量值。
int buttonId = 0;void buttonCallback(int event) { printf("buttonId:%d event=%d\n", buttonId, event);}void setButtonCallbacks() { for (int i = 0; i < BUTTON_MAX; ++i) { buttonId = i; setButtonCallBack(BUTTON_IDOFFSET + i, &buttonCallback); }}
该源代码的问题很明显。全局变量buttonId只有一个,所有回调都使用for循环最后的值。当然如果不使用全局变量,回调方法将按钮的ID作为函数参数传递,就能解决该问题。
void buttonCallback(int buttonId, int event) { printf("buttonId:%d event=%d\n", buttonId, event);}
但是,回调方在保持回调函数的指针以外,还必须保持回调方的按钮ID。
C++和Objective-C使用类可保持变量值且能够多次持有该变量自身。它会声明持有成员变量的类,由类生成的实例或对象保持该成员变量的值。我们来思考一下刚才例子中用来回调按钮的类。
@interface ButtonCallbackObject : NSObject{ int _buttonId;}@end @implementation ButtonCallbackObject- (id) initWithButtonId:(int)buttonId { self = [super init]; if (self) { _buttonId = buttonId; } return self;} - (void)callback:(int)event { NSLog(@"buttonId:%d event=%d\n", _buttonId, event);}
如果使用该类,由于对象保持按钮ID,因此回调方只需要保持对象即可。可如下使用:
void setButtonCallbacks() { for (int i = 0; i < BUTTON_MAX; ++i) { ButtonCallbackObject *callbackObj = [[ButtonCallbackObject alloc] initWithButtonId:i]; setButtonCallbackUsingObject(BUTTON_IDOFFSET, callbackObj); }}
但是,由此源代码可知,声明并实现C++、Objective-C的类增加了代码的长度。
这里我们就要用到Blocks了。Blocks提供了类似由C++和Objective类生成实例或对象来保持变量值的方法,其代码量与编写C语言函数差不多。如“带有局部变量的值”,Blocks保持局部变量的值。下面我们使用Blocks实现上面的按钮回调:
void setButtonCallbacks() { for (int i = 0; i < BUTTON_MAX; ++i) { setButtonCallbackUsingBloc(BUTTON_IDOFFSET + i, ^(int event) { printf("buttonId:%d event=%d\n", i, event); }); }}
Blocks的语法和保持局部变量在后面详细说明,该源代码将“带有局部变量i值的匿名函数”设定为按钮的回调。Blocks中将该匿名函数部分称为“Block literal”,或简称为“Block”。
像这样,使用Blocks可以不声明C++和Objective-C类,也没有使用静态变量、静态全局变量或全局变量时的问题,仅用编写C函数的源代码量即可使用带有局部变量值的匿名函数。
另外,“带有局部变量值的匿名函数”这一概念并不仅指Blocs,它还存在于其他许多程序语言中。在计算机科学中,此概念也称为闭包(Closure)、lamdba计算等。
- Block 1:什么是Blocks
- Block(一)---Blocks概要
- 什么是Block
- 什么是 block
- 什么是block scope?
- Brief Intro to Blocks 2:Block Syntax
- Block的使用(Working with Blocks)
- IOS block编程指南 4 声明和创建blocks
- 声明和创建Blocks 3.1 声明一个block的引用
- 关于linux文件Blocks和Block size的一些解析
- Sparse Matrix --- (1) Blocks
- blocks
- Blocks
- Blocks
- Blocks
- Blocks
- Blocks
- Blocks
- UML-顺序图(2)
- hdu 1015 Safecracker 枚举
- 第六周作业(课本例题)
- 编程小题
- SDOJ 2138图结构练习——BFSDFS——判断可达性(图的深度优先遍历)
- Block 1:什么是Blocks
- 滑动菜单栏(一)开源项目SlidingMenu的使用
- Linux JDK8
- 忙里偷闲( ˇˍˇ )闲里偷学【C语言篇】——(2)准备知识
- web2py 操作cookie 深入思考
- pendingIntent
- POJ 1948 Triangular Pastures(双线性dp)
- 利用GBK双字节编码突破PHP单引号转义限制进行SQL注入
- java 学习 BigInteger Demo