您的位置:首页 > 移动开发 > IOS开发

初探iOS中的Block(代码块与闭包)

2013-09-11 21:38 239 查看
支持原创,转载请注明博主与博文链接,3Q


/article/7601633.html

—— 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

可以看到,两个方法都可以解决问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: