IOS Blocks 详细介绍

  • block类似与函数指针,与函数指针的区别在于其可以捕获(capture)其定义时作用域内的变量,当在其他位置调用时仍然可以使用。

  • block是一种Objective-C对象,其数据结构中存在isa指针,isa指针指向&_NSConcreteStackBlock或&_NSConcreteGlobalBlock。

  • block通常是在函数内定义的,此时block对象是在栈内分配的,若此block只在定义它的函数内使用,则block就会一直存在在栈中,当函数返回时,栈帧回退,定义的block也随之销毁。

  • 当block需要在其定义时的函数外使用时,需要对其进行copy处理,copy的意义在于将block在堆中分配一份,这样当定义函数的栈帧回滚时,block仍然存在。
    1. copy操作可以向block对象发送-copy消息,也可使用C函数Block_copy(),释放操作则为-release或Block_release().
    2. 对block应该总是进行copy操作,因为对栈内分配的block拷贝会将其拷贝到堆中,对已经在堆中的block进行copy,则只会增加retain count,与retain操作相同。而对栈内分配的block进行retain操作则不会有任何影响。
  • block之所以强大在于其可以捕获(capture)其引用的变量,包括局部变量,指针,Objective-C对象,全局变量,static变量等。
    1. 全局变量,static变量在block内是直接访问的,因为其内存区域一直存在。
    2. 对于引用的局部变量,block使用的方法是将局部变量拷贝到block内部,并声明为const,这样在block中将只能使用引用到局部变量的初始值,而不能进行修改。
    3. 局部指针变量被block const拷贝后仍然是指针,虽然指针本身是const的,但其指向的对象仍然是可以修改的。
    4. 如果想对引用的局部变量进行修改,可以在局部变量上使用__block标示符号,使用__block后的局部变量会以一种指针的方式被间接引用,引用其的block不会进行const copy,所有block、包含定义的函数内看到的__block局部变量都是同一份,任何block中对此变量进行修改都可以被其他block看到。在引用__block局部变量的block被从栈拷贝到堆时,__block变量也会被拷贝到堆中,所以__block变量在运行时是会变化的。
    5. 在block引用Objective-C对象时,会对Objecitive-C对象进行retain操作,当block销毁时再进行release操作。如果不想对引用的Objecitive-C对象做retain处理,则可以使用__block 标示要引用的Objecitive-C对象,这只适用于非ARC的代码中。在ARC代码中,即使用__block标示,在block引用时仍然会retain,这中情况下则需要使用__weak(iOS5)或__unsafe_unretained(iOS4,不支持weak的环境)。
    6. 如果在类方法中定义的block引用了类中的实例变量,则实际上是通过self以self->instanceVar的方式引用的,这是会对self做retain操作。这样会出现retain cycles,为了避免这中情况,一般会声明一个局部变量blockSelf,将self以__block或__weak,__unsafe_unretained的方式赋值给blockSelf,在block代码中则通过blockSelf引用类示例变量,这样可以避免retain cycles。

    参考:
    Block Implementation Specification
    Language Specification for Blocks
    Blocks Programming Topics
    How blocks are implemented (and the consequences)
    Blocks, Episode 2: Life Cycles
    Programming with C Blocks
    Using Blocks: Understanding the Memory Management Rules
    Friday Q&A 2008-12-26 blocks
    Friday Q&A 2009-08-14: Practical Blocks
    Friday Q&A 2010-04-30: Dealing with Retain Cycles
    Friday Q&A 2011-09-30: Automatic Reference Counting
    Block的Retain Cycle的解决方法

本文出自 清风徐来,水波不兴 的博客,转载时请注明出处及相应链接。

本文永久链接: http://www.winddisk.com/2012/08/07/blocks/

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值