iOS成长之路基础篇 – (5) 认识 OC 中的 Block

iOS成长之路基础篇 – (5) 认识 OC 中的 Block

这一篇,我将总结一下OC语言的一个亮点——Block类型。Block是iOS4 和Mac OS X 10.6以后引进的对C语言的扩展。Block在OC中其实也是对象,它封装了一段代码,这段代码在后面任何时机都能被调用。在Apple最新的Swift语言中也有一个相似的特性,叫闭包,也就是说现代的高级语言,基本都会有这种闭包式编程。下面,我们先详细说一说Block类型。

Block数据类型

block是用来保存一段代码,在后面的编码中可以使用中它完成一些功能。block可以作为函数的参数或者函数的返回值,其本质相当于一个函数,所以也可以带参数或者返回值,与C语言中的函数指针很类似。在Apple官方文档中,可以看到建议尽量多用block。

block语法基础

block的标记是:^。其形式与函数很像:

  1. 可以保存代码段;
  2. 有返回值。或者为一个数据类型,或者为void;
  3. 有形参,可以传递参数;
  4. 调用方式一致。

block定义的形式:

返回数据类型 (^block名称)(形参的数据类型) = ^(形参,没有可以省略括号){

    // 代码块 

};

好的,这里我们举个例子:

// 这是一个void返回值的block,block的参数列表为空
void (^myBlock)() = ^{

    // block 中的代码块

};

// 这是一个返回值为int,参数列表有两个参数的block
int (^sumBlock)(int, int) = ^(int a, int b){

    // ......
    return a+b;

};

// 我们还可以将block的定义分开写
int (^minBlock)(int, int);      //定义block变量
// 具体实现block,相当于给变量赋值
minBlock = ^(int a, int b){     

    return a>b?b:a;

};

// 还可以使用typedef来定义block类型
// 新类型定义
typedef int (^myBlock)(int, int);
// myBlock是一个我们自定义的新数据类型
myBlock b = ^(int a, int b){

    return a+b;

};

看了上面的例子,是不是感觉这个block和函数定义很像,只是前面的OC定义的标识符号等感觉有一点奇怪,这个我刚开始学习的时候也被吓到了,这都什么呀,看不懂,后来理解的多了,也就越觉得跟函数一样了。有几点需要注意的,下面这个总结一下。

block访问变量的原则

  1. block内部对外部的变量只可以读取;
  2. 默认情况下,block内部不能修改外面的变量,修改编译器就会报错;
  3. 给局部变量加上__block关键字,这个局部变量可以在block内部修改。

Block内存分析

Block存储区域分为三种:

  1. _NSConcreteStackBlock(栈)
  2. _NSConcreteGlobalBlock(全局,堆)
  3. _NSConcreteMallocBlock(堆)

在ARC中,当block被定义之后,就会被分配到heap内存。这样block就与其他变量类似,接受引用计数管理。如果我们的block在定义中没有捕获程序中上下文的变量时,编译器在编译阶段就能够知道我们block的所有信息,会将其保存在全局内存,不会收到release消息。

总结

block的基本内容就是上面那些,但是block在iOS开发中的使用之广,可以说是贯穿整个开发,Block在开发中能代替下一篇我要总结的protocol协议,在开发中网络请求需要异步处理,任务完成时回调,处理消息监听回调处理,错误回调处理,枚举回调,视图动画、变换等场合就会用到Block。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注