支持原创,转载请注明博主与博文链接,3Q
http://blog.csdn.net/yang8456211/article/details/11581197
—— by atany
一、Block是什么?
Block就是一个包含函数体的对象,有时候也被叫做闭包。
概念可能还是有点模糊,没关系,我们来看看用法。
二、Block的声明与创建。
代码块的基本结构为:
returnType (^blockname)(list of arguments) =^(arguments){ body; }
举个例子:我们定义一个作用为打出“Hello + 名字”的闭包。
void(^sayHelloBlock)(NSString*) = ^(NSString *personName){ NSLog (@"Hello %@", personName); };
对应的拆解:
void:返回值.
^sayHelloBlock:[^]符号声明block对象,“sayHelloBlock”为blockname。
(NSString*):block的输入参数列表。(也可以写成NSString *personName的完整形式)
(NSString *personName):详细参数,必须写完整形式,变量personName会在block中用到。
{ NSLog (@"Hello %@", personName);};:body,也就是block的内容,这里是打印出一句话。
声明与创建完成后,我们来看看Block的使用:block的使用与函数十分相似,直接使用(block名称+参数)的形式。
sayHelloBlock(@"atany");
打印出:2013-09-1120:18:54.130 TestBlock[3137:c07] Hello atany
三、Block的特性
1) Block可以访问函数其他的内部变量
NSString *person = @"Mary"; void(^sayHelloBlock)()= ^{ NSLog(@"Hello %@",person); }; sayHelloBlock();
输出:2013-09-11 20:26:06.050TestBlock[3176:c07] Hello Mary
可以看到person对象在Block的外部,但是Block却能够访问到person对象的值Mary,这也是block最重要的一个特性。
2) Block声明时会捕捉创建点的状态。
NSString *person = @"Mary"; void(^sayHelloBlock)()= ^{ NSLog(@"Hello %@",person); }; sayHelloBlock (); person = @"Peter"; sayHelloBlock();
输出:
2013-09-11 20:28:38.423 TestBlock[3200:c07] Hello Mary
2013-09-11 20:28:38.424TestBlock[3200:c07] Hello Mary
为什么会这样呢?怎么没有打出Hello Peter?
原来当程序执行到Block的声明时,Block会记录创建点所用资源的状态,此时person的值为“Mary”,Block保存这个值的副本,再次使用时直接调用副本。所以即使在后面person的值变为了“Peter”,副本的值也不会改变。
那怎么办呢?有两种解决方法。
1) 修改对象为静态.
static NSString *person= @"Mary";
2) 在对象声明前添加__block.
__block NSString *person = @"Mary";
输出:
2013-09-11 20:35:29.838TestBlock[3244:c07] Hello Mary
2013-09-1120:35:29.840 TestBlock[3244:c07] Hello Peter
可以看到,两个方法都可以解决问题。