美文网首页
Block类型和捕获变量

Block类型和捕获变量

作者: 分流替躺欧阳克 | 来源:发表于2019-05-24 22:42 被阅读0次

    Block类型

    1:类型区别特征

    Block是OC的对象,他也有类型,我在打印[block class]的时候可以看到有不同的block类型。

    block 有三种类型,凡是访问了auto变量的便是__NSStaticBlock__类型,没有访问auto的是__NSGlobalBlock__,调用了copy的是__NSMallocBlock__。

    他们的内存区域:

    1:在全局区的__NSGlobalBlock__

    2:在栈空间的__NSStaticBlock__

    3:在堆空间的__NSMallocBlock__

    这三个都继承于NSBlock,NSBlock继承于NSObect。

    2:block的copy操作

    在栈空间创建的block是__NSStaticBlock__,对它进行copy操作会把它变成__NSMallocBlock__类型,另外说明的是要在Objective-C Automatic Reference Counting 设置是否是ARC YES是ARC,需要调整成MRC模式才能看到类型转换。__NSMallocBlock__类型的block才能赋值给全局变量。如下

    block = [^{NSLog("This block type is Malloc")} copy];

    在ARC的环境下,一些情况,编译器会将block自动 copy搬到堆上去;

    1:block作为返回值。

    2:将block赋值给强指针__strong

    3:block作为Cocoa API中方法名含有usingBlock的方法参数时。

    4:block作为GCD API的方法参数时。

    3:对象类型的auto变量

    当我们的block对对象类型的变量捕获时,底层编译的代码__main_block_desc_0里会产生两个函数__main_block_copy_0和__main_block_dispose_0,block结构体里面也会多个成员接收被捕获的变量对象Person

    在栈上的block 不会对auto类型的对象产生强引用。

    如果block被拷贝到堆上,会调用内部的copy函数 ,copy函数内部会调用_Block_object_assign函数。_Block_object_assign函数会根据auto变量的修饰符(__strng,__weak, __unsafe_unretained)做出相应的操作。类似retain(强引用,弱引用)

    如果block从堆上移除,会调用block内部的dispose函数。dispose函数内部会调用__Block_object_dispose函数 ,这个函数会自动释放引用的auto变量,类似release。

    当block内部捕获了对象型auto变量时,block的核心结构体里会多个成员接收变量

    __main_block_desc_0结构体里会多两个函数

    捕获变量

    变量分全局变量,和局部变量,其中局部变量分auto和static类型。

    我们平常声明变量 比如:int a = 10;默认类型就是auto,离开了作用域就会销毁。

    如果,在block内访问外部的变量,block会在内部声明成员接受外部的值,这叫捕获变量,auto是值捕获,在block里改变值不会改变作用域外面的值,static是指针捕获,在block内改变值会改变作用域外的值。全局变量不会被捕获,block可以直接调用。

    图-01

    上图代码中age_,和height_是全局变量。上面那段代码,编译后的C++代码如下:

    图-02

    __block 修饰符所干的事

    我们在经常会在block修改外部变量,当我们修改外部的变量是static或者只是使用指针类型传递的变量时,不需要加__block,而要修改它的值就需要加__block.

    __block到底做了什么,如下代码

    在编译后的C++代码是:

    由上面三幅图可以看出,当我们用__block修饰变量时,底层会对变量进行一个包装,把变量封在一个结构体里,如果被修饰的是对象,那么结构体里还会有copy和dispose函数,对对象进行retain和copy操作

    相关文章

      网友评论

          本文标题:Block类型和捕获变量

          本文链接:https://www.haomeiwen.com/subject/ozxozqtx.html