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

支持原创,转载请注明博主与博文链接,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

可以看到,两个方法都可以解决问题。


你可能感兴趣的:(ios,block,iOS闭包,iOS代码块,iOS基础学习)