iOS DeveloperiOS开发iOS Developer - Block

Block(块)

2016-09-25  本文已影响213人  Ryker_Bay

定义

带有局部变量(自动变量)的匿名函数

ps :
“带有局部变量”:可以获取到块外面的变量(将变量放在自身(block)的结构体中;获取的只是改变量的瞬时值,后面对变量的修改不会使块中的变量也被修改),但是只能读取;
要改写的话需给变量前面加"__block"修饰符 _(将该变量变成和Block一样的结构体实例,并在自身的结构体添加一个对结构体中值的指针引用;分开两个结构体(block的结构体 , 变量的结构体)是为了能够在多个Block中用到_block变量)

本质

C语言中的结构体和函数,OC语言中对象

语法

^ 返回值类型 参数列表 表达式(斜体代表可省略)

ps:
省略返回值类型时,如果表达式中有return就使用该返回值的类型,如果没有return就使用void类型;表达式中含多个return语句时,所有return的返回值类型必须一致

分类

所属类 说明
栈块 _NSConcreteStackBlock 编译器会给每个块分配好栈内存, 然而等离开了相应的范围之后,编译器有可能把分配给块的内存覆写掉。
堆块 _NSConcreteMallocBlock 带引用计数的块对象;栈块通过copy方法可成为堆块
全局块 _NSConcreteGlobalBlock (存储域为程序的数据区域 .data区) 块不会捕捉任何状态(比如外围的变量等),运行时也无须有状态来参与。块所使用的整个内存区域,在编译期已经完全确定了。

ps:全局块:对其的拷贝操作是个空操作,因为全局块决不可能为系统所目收。这种块实际上相当于单例。下面就是个全局块:

void (^ablock)() = ^{
    NSLog(@"This is a block");

}

由于运行该块所需的全部信息都能在编译期确定,所以可把它做成全局块。这完全是种优化技术:若把如此简单的块当成复杂的块来处理,那就会在复制及丢弃该块时执行

9460be12gw1eyxyexv5omj20zi0t6tdm.jpg

)

从栈到堆

对于Block (用copy方法)

使用场景:向方法或函数的参数中传递Block时
不需手动复制的情况:

源存储域 复制效果
栈 -> 堆
引用计数增加
程序的数据区域 什么也不做

对于__block变量

跟随Block移动:当一个引用__block变量的Block从栈到堆时,__block变量也从栈到堆,并持有该变量;当有另外一个也引用了该__block变量的Block从栈到堆时,该Block也持有该变量并且该变量引用计数加一,

参考资料:
《Objective-C高级编程》

上一篇下一篇

猜你喜欢

热点阅读