Object-C高级编程读书笔记(1)——Block的基本概念

来源:互联网 发布:蜘蛛侠淘宝上货软件 编辑:程序博客网 时间:2024/04/29 13:46

在OC中,引入了Block的概念,同时也有很多具体的应用。其功能类似于C语言中的函数指针,可将函数作为变量保存,传递,执行。

Block的声明方式

<span style="font-size:14px;">^返回值类型 参数列表 表达式例如^int(int count){ return count + 1;}</span>

Block变量

<span style="font-size:14px;">返回类型(^变量名称)(参数列表)例如, 一个叫做blk1的block变量int(^blk1)(int)</span>

Block类型的typedef

有时候我们需要将block类型作为函数参数或返回值,但block的语法会使函数的声明变得过于臃肿,可使用typedef为block类型起别名

<span style="font-size:14px;">typedef 返回类型(^别名)(参数列表)例如,typedef int(^blk_t)(int);则可用int fun(bulk_t blk);</span>

Block是带有自动变量值的匿名函数

在 OC高级编程这本书中,作者将block概况为“带有自动变量值的匿名函数”。该怎么理解它呢?

匿名函数,不用多说,重点则是“带有自动变量值”。

“带有自动变量值”可从两个点来理解

1.block内能够保持block外的变量值

若block内部使用了block外部的一个变量值,则block块则会对该变量做一个拷贝,即使block外该变量已经超出了作用域而释放,但block内部仍有一份拷贝值可以使用。

例如,在NSURLConnection中,其complete block是不会立即执行的(需要等到起URL操作完成才会执行),即使Block外的变量值已经失效释放,但是在URL 结束后调用complete block时,该变量仍可以在block中使用。(具体原因在后面会有涉及)

2.block是截取的变量的瞬时值

在前面已经说过,block会对block外的变量保持一份副本,来保证block执行时,该变量不会无法使用。但是应该注意的是,block只是保留的该变量传入block时的当时值,在block定义之后的对于该变量的任何改变,均不会影响到block内部使用该变量时的值。

例如

<span style="font-size:14px;">int var = 10;void (^blk)(void) = ^{printf("var =%d", var)};val = 2;blk(); // 当blk执行时,会使用其定义时var的瞬时值,即显示‘var = 10’</span>

3.__block说明符

默认的,对于block外的变量,block块内只能读,不能改变,否则会引起编译错误。但是在变量前加上__block,则告知编译器该变量可以在block内改变,编译通过。注意这里所说的变量改变,是说变量自身的改变,而不是变量不能够被操作。如对于截获的OC对象,我们不能够改变其对象指针所指向的内存,但是可以通过调用对象方法,改变对象内部的值。如

NSMutableArray对象

<span style="font-size:14px;">id array = [[NSMutableArray alloc] init];void(^blk)(void)=^{   id obj =[ [NSObject alloc] init];   [array addObject:obj];}</span>

这是可以通过编译的,而

<span style="font-size:14px;">id array = [[NSMutableArray alloc] init];void(^blk)(void)=^{   array = [[NSMutableArray alloc] init]; // 改变了array本身}</span>
则会引发编译错误。


0 0
原创粉丝点击