iOS中block的使用

在面向对象语言中,类封装了数据和这些数据相关的行为。然而有些情况下,一个简单的任务和已通过一段代码块和少数几个变量来完成。在iOS4中有了代码块block的概念,这篇文章就对block的使用做一个简单的整理。

0. Block概述

Block是和iOS4一同的,它是C语言级别和运行时方面的一个特征。Block封装了一段代码逻辑,也用{}括起,和标准C语言中的函数/函数指针很相似,此外就是blokc能够对定义环境中的变量可以引用到。这一点和其它各种语言中所说的“闭包”是非常类似的概念。

在iOS4中,block有很多应用场景,比如对代码封装作为参数传递。这在使用dispatch并发(Operation中也有BlockOperation)和completion异步回调等处都广泛应用。

1. Block的基本使用

声明:(返回类型)(^声明的block名称)(参数列表);

实现:^(参数列表){代码块}

赋值的例子:

double (^multiplyTwoValues)(double, double) =
                              ^(double firstValue, double secondValue) {
                                  return firstValue * secondValue;
                              };

有时为了方便,用typedef给出定义,在苹果的官方文档里,建议出现多次的block使用typedef定义。

而block的调用,则十分简单:block名称(参数列表);

2. 使用中的注意点

有如下一些注意点:

  • 对定义环境的变量使用。默认是以const的方式使用,这有点像函数的const参数传递,如过需要block内修改可变,则使用__block,这样做存储就实现了共享,包括块中的递归应用和定义环境上下文中的多个block使用。block通常定义在栈帧当中,而当所处的栈帧被销毁的时候,block以及引用到的__block变量将会依然有效。
  • 引用类型问题。block中的引用默认都是强引用,必要的时候需要使用__weak,同delegate使用的注意一样,避免循环引用。此外,苹果文档中还给出了对instanceVariable和对localVariable引用不同的例子,注意体会下。
  • copy。在类属性中,要使用copy。此外,对block进行copy要使用Block_copy()/Block_release()。
  • 苹果文档中几种需要避免使用的方式。《Blocks Programming Topics》中Using Blocks中的例子,实际上就是要注意block定义的位置与其上下文的关系。
  • 有关Block的地址/引用。注意这篇文章中最后例子中的问题:http://www.cnblogs.com/kesalin/archive/2013/04/30/ios_block.html                        我的理解是Block的地址发生了变化,最终的问题是对Block引用地址释放时的野指针错误。

3. 联想Java中匿名类使用

Java7以及之前的各个版本中,没有“闭包”的概念(感兴趣的可以看今年3月Oracle发布的Java8),回调(callback)使用内部类实现。在方法定义中使用匿名内部类,需要注意的一点是匿名类中对外部方法参数的使用,要求参数只能是final的。

其实在iOS中,对于block使用外部方法的参数,也只能是const的,不能对参数进行__block要求。

更多内容,可以参考苹果官方文档:

Working with Blocks

Blocks Programming Topics

相关文章:

此条目发表在 iOS, iOS开发基础, Java, Objective-C, 开发, 计算机技术 分类目录,贴了 , , , , , 标签。将固定链接加入收藏夹。

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>