美文网首页
block详解<3>: block在内存区域中是如何分布的

block详解<3>: block在内存区域中是如何分布的

作者: 菜小狼 | 来源:发表于2016-09-23 16:12 被阅读0次

如果大家还有映像的话,我们在前面讲解结构体 _block_impl的时候,里面有一个成员叫isa,这个代表了block在内存区域中的分布。如果你看了一些关于block的文章,isa会有三种取值:

isa = &_NSConcreteStackBlock;
isa = &_NSConcreteMallocBlock;
isa = &_NSConcreteGlobalBlock;

但是clang出来的文件,里面都是第一种,说明这并不是block在内存中的真正分布。真正的分布,我们可以通过打印来确定。


屏幕快照 2016-09-22 2.35.54 PM.png 屏幕快照 2016-09-22 2.49.47 PM.png

第二张图的打印结果是NSMallocBlock,同时我又试了其他的几种情况,发现都是NSMallocBlock,说明在ARC环境下,栈上的block默认都会被拷贝到堆上,也就是说,在ARC环境下,block只有两种类型:NSGlobalBlock 和 NSMallocBlock。那么到底有没有特殊的情况呢?后来查查资料,发现还真有。

屏幕快照 2016-09-22 5.09.57 PM.png

执行上面的代码的时候,直接crash了,从错误的提示可以看出,是某个东西的内存过早的释放了。我们仔细观察一下控制台,发现数组的第一个元素是NSMallocBlock类型,这是被分配在堆上的block;数组的第二个元素有点儿问题:发现它的内存地址跟argv的格式比较像,而argv是函数的参数,内存是被分配在栈内存上的,所以第二个block也是被分配在栈内存上的,并没有被拷贝到堆内存上。然后我们换一种写法:

屏幕快照 2016-09-22 5.21.23 PM.png

发现可以正常运行,并且打印的结果也是我们想要的。

我们再看一下上面的数组的初始化函数

+ (instancetype)arrayWithObjects:(ObjectType)firstObj, ... NS_REQUIRES_NIL_TERMINATION;

这个函数是一个可变函数,只有第一个参数被显示的申明为ObjectType类型,也就是id类型,其他的参数并没有被显示的申明为id类型。这也验证了第一种情况下第一个block被分配在堆上,第二个block被分配在栈上。而我们的第二种写法是,先申明一下block,在block到底是什么一文中,我们已经说了,block其实就是一个函数指针,也可以说它是一个id类型,所以在第二种写法下,两个block都被显示的申明为id类型,所以都被分配在堆上,所以第二种情况没有问题。

由此我们可以得出一个结论:block作为函数的参数时,一定要被显示的申明为id类型,才会被分配在堆上。
参考文章

ARC 下向 NSArray 添加 Block 元素的一个小坑

相关文章

  • block详解<3>: block在内存区域中是如何分布的

    如果大家还有映像的话,我们在前面讲解结构体 _block_impl的时候,里面有一个成员叫isa,这个代表了blo...

  • Block探索

    Block内存关系Block经典问题循环引用&解决Block底层分析Block底层HooK 程序占用内存分类 栈区...

  • Block

    block的内存管理: 无论当前环境下是arc还是mrc,只要block没有访问外部变量,block始终在全局区 ...

  • Block

    Block block内存管理 无论是MRC还是ARC,只要block没有访问外部变量,blokc始终在全局区 M...

  • 内存管理

    IOS的内存分布是有五个区: 栈区:函数,⽅法,常量,指针 堆区:通过alloc分配的对象,block copy ...

  • iOS面试题-block

    block的内存管理 无论当前环境是ARC还是MRC,只要block没有访问外部变量,block始终在全局区 MR...

  • iOS 为什么Block用copy关键字

    Block在没有使用外部变量时,内存存在全局区,然而,当Block在使用外部变量的时候,内存是存在于栈区,当Blo...

  • 为什么Block用copy关键字

    Block在没有使用外部变量时,内存存在全局区,然而,当Block在使用外部变量的时候,内存是存在于栈区,当Blo...

  • Block的类型划分

    block如何分类?其实blcok的分类主要是根据block的内存管理来说的,系统把Block分为3类:NSGlo...

  • Objective-C Block底层原理

    Block的内存结构 在苹果官方文档中,给出了block的结构体定义: Block是如何捕获参数的: OC代码如下...

网友评论

      本文标题:block详解<3>: block在内存区域中是如何分布的

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