美文网首页
block的内存管理

block的内存管理

作者: coderJerry01 | 来源:发表于2016-07-03 08:23 被阅读40次

block封装了一段代码,这段代码可以在任何时候执行。Block可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值。

block的使用就像函数指针,不过与函数最大的不同是:block可以访问函数以外、词法作用域以内的外部变量的值。换句话说,block不仅可以实现函数的功能还能携带函数的执行环境,也就是说block就是能够读取其它函数内部变量的函数。block的内存管理需要开发人员自己管理,错误的内存管理会造成循环引用内存泄漏或者内存因为提前释放造成crash。

首先要知道的就是block包含两部分:

1>block所执行的代码。

2>block执行时所需要的外部变量值的数据结构。

block 的内存是分配在栈上的,栈上的东西,在不需要的时候系统会自动收回,如果 block内部强引用了外部的一些变量,就会造成内存的泄露,此时 copy 的作用就是把栈上分配的 block 拷贝到堆上。但是在 ARC 模式下 block 的 copy 属性系统会自动添加的。

block的类型

NSGlobalBlock:位于内存全局区

存储在程序的数据区域(text段),我们只要实现一个没有对周围变量没有引用的Block,就会显示为是它,对于Global的Block,我们无需多处理,不需retain和copy,即使copy,也不会我们以为的copy到堆区,内存不会发生变化!操作都无效,例如:

int c = 100;

int(^globalBlock)(int,int) = ^int(int a, int b){

return  a + b;

};

float sums = globalBlock(10,20);

NSLog(@"globalBlock 类型 %@--%@", globalBlock,[globalBlock copy]); //block 类型

结果:

<__NSGlobalBlock__: 0x10abf30b0>--<__NSGlobalBlock__: 0x10abf30b0>

原文鏈接:http://www.jianshu.com/p/ca55bfc2cb7d

NSStackBlock:位于内存栈区

位于栈内存,函数返回后Block将无效;对于定义的Block加入了对定义环境变量的引用,也就是说内部使用了外部变量,就是NSStackBlock。对于Stack的Block,如果不做任何操作,随栈自生自灭。而如果想让它获得比stack更久的生命,那就调用Block_copy(),或者copy修饰,让它搬家到堆内存上,这也是我们为什么一直用copy修饰Block的原因。对于NSStackBlock栈区Block,我们分MAR和ARC两种情况讨论,因为两种模式下的内存机制是不同的。

在MRC模式下,分析如下示例打印结果:

int MRC_Value = 100;

void (^MRC_Block)(void) = ^{

//知识在里面使用MRC_Value,并没有调用打印

NSLog(@"MRC_Value :%d", MRC_Value);

};

NSLog(@"block is %@--%@", MRC_Block,[MRC_Block copy]);

//结果:

block is <__NSStackBlock__: 0x7fff5b244a40>--<__NSMallocBlock__: 0x7fe380f29010>--

结果分析:当Block中使用了外部变量,Block为NSStackBlock类型,存储在栈区,当函数执行结束后,改Block就会被释放,调用copy后,栈区Block被copy到了堆区NSMallocBlock(下面会介绍)。

在ARC模式下,分析以上相同示例打印结果:

block is <__NSMallocBlock__: 0x7fea01693750>--<__NSMallocBlock__: 0x7fea01693750>--

分析结果:在ARC模式下,没有了__NSStackBlock__类型,不要认为ARC没有了栈区Block这种类型,其实在ARC下,生产的Block默认也是NSStackBlock类型,只是在变量赋值的时候,系统默认对其就行了copy,从NSStackBlock给copy到堆区的NSMallocBlock类型,而在非arc中,则需要手动copy.。

文/河南蓝鸥科技有限公司(簡書作者)

原文鏈接:http://www.jianshu.com/p/ca55bfc2cb7d

NSMallocBlock:位于内存堆区

只需要对NSStackBlock进行copy操作就可以获取,所以,当我们定义的Block要在外部回调使用的时候,在MRC下,我们需要copy的堆区,永远的持有,不让释放;在堆区的NSMallocBlock,我们可以对其retain,release,copy(等价于retain,引用计数的加一)。在ARC下,系统会给我们copy到堆区,不需我们管理了,所以个人还是喜欢ARC的模式,避免了很多不必要的麻烦。

文/河南蓝鸥科技有限公司(簡書作者)

原文鏈接:http://www.jianshu.com/p/ca55bfc2cb7d

相关文章

  • Block内存管理实例分析

    Block内存管理实例分析 Block内存管理实例分析

  • Block内存管理

    对block自身内存的管理 对于block,有两个内存管理方法:Block_copy, Block_release...

  • iOS内存管理详解

    目录 block内存管理 autorelease内存管理 weak对象内存管理 NSString内存管理 new、...

  • Block 使用总结

    Block 内存管理: Block 内存主要分派到 NSGlobalBlock(data area),NSMall...

  • iOS面试之Block大全

    Block Block内容如下: 关于Block 截获变量 __block修饰符 Block的内存管理 Block...

  • iOS面试之Block模块

    Block Block内容如下: 关于Block 截获变量 __block修饰符 Block的内存管理 Block...

  • Block

    一、Block本质 二、 BlocK截获变量 三、__block 修饰变量 四、Block内存管理 五、Block...

  • Block

    Block介绍 截获变量 __block修饰符 Block的内存管理 Block的循环引用 一、Block介绍 1...

  • block的内存管理

    block的内存默认放在栈中,(开发人员不需要管理block内存),block所引用的对象的retainCount...

  • block的一些注意事项

    Block的使用注意: block的内存管理(注意循环引用,默认在栈中(不需要内存管理),通过copy就在在堆中,...

网友评论

      本文标题:block的内存管理

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