block及注意点

Block是C语音级别和运行时放面的一个特征。Block封装了一段代码逻辑,也用{}括起,和标准C语音中的函数/函数指针很相似,此外就是block能够对定义环境中的变量可引用到。这一点和"闭包"概念类似。

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

1.Block的基本使用

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

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

建议出现多次的block使用typedef定义。

block的调用:   block名称(参数列表);

2.使用中的注意点

(1)对定义环境的变量使用。默认是以const的方式使用,这有点像函数的const参数传递,如过需要block内修改可变,则使用__block,这样做存储就实现了共享,包括块中的递归应用和定义环境上下文中的多个block使用。block通常定义在栈帧当中,而当所处的栈帧被销毁的时候,block以及引用到的__block变量将会依然有效。

(2)引用类型问题。block中的引用默认都是强引用,必要的时候需要使用__weak,同delegate使用的注意一样,避免循环引用。此外,苹果文档中还给出了对instanceVariable和对localVariable引用不同的例子,注意体会下。

(3)copy。在类属性中,要使用copy。此外,对block进行copy要使用Block_copy()/Block_release()。

3.联想Java中匿名类使用

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

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

4.Block与对象的关系

Block是OC语言中的对象。Block对象与一般的类实例对象有所不同,一个主要的区别就是分配的位置不同,block默认在栈上分配,一般类的实例对象在堆上分配。

retain是对一个在堆中分配内存的对象的引用计数做了增加,执行release操作的时候检查计数是否为1,如果是则释放堆中内存。而对于在栈上分配的block对象,这一点显然有所不同,如果方法调用返回,栈帧上的数据自然会作废处理,不像堆上内存,需要单独release,就算NSArray对block对象本身做了retain也无济于事。

用一个方法对block数组做初始化是否有可能方案呢。答案是肯定的,不过需要真正了解block的使用,至少要会用Block_copy()和Block_release()。

5.Block的类型和使用

NSGlobalBlock 显示的是没有对周围变量没有引用的Block。

NSStackBlock 是其中加入了对定义环境变量的引用。

NSMallockBlock  对一个NSStackBlock对象使用了Block_copy()或者发送了copy消息,就会得到NSMallocBlock。

对于Global的Block,我们无需多处理,不需retain和copy,因为即使你这样做了,似乎也不会有什么两样。对于Stack的Block,如果不做任何操作,就会向上面所说,随栈帧自生自灭。而如果想让它获得比stack frame更久,那就调用Block_copy(),让它搬家到堆内存上。而对于已经在堆上的block,也不要指望通过copy进行“真正的copy”,因为其引用到的变量仍然会是同一份,在这个意义上看,这里的copy和retain的作用已经非常类似

在类中,如果有block对象作为property,可以声明为copy。

参考:http://www.molotang.com/articles/1691.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 《Objective-C高级编程》这本书就讲了三个东西:自动引用计数、block、GCD,偏向于从原理上对这些内容...
    WeiHing阅读 13,327评论 10 69
  • 前言 Blocks是C语言的扩充功能,而Apple 在OS X Snow Leopard 和 iOS 4中引入了这...
    小人不才阅读 9,143评论 0 23
  • 一、Objective-C发展史 Objective-C从1983年诞生,已经走过了30多年的历程。随着时间的推移...
    没事蹦蹦阅读 11,124评论 12 34
  • iOS代码块Block 概述 代码块Block是苹果在iOS4开始引入的对C语言的扩展,用来实现匿名函数的特性,B...
    smile刺客阅读 6,951评论 2 26
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,378评论 30 472