首页 > 代码库 > blcok的总结

blcok的总结

没有引用外部变量的block  为 __NSGlobalBlock__ 类型(全局block)

 

MRC:

 

引用外部变量的block  为 __NSStackBlock__ 类型(栈区block)  栈区中的block,申明属性用copy,可以从栈区拷贝到堆区

使用copy修饰的原因是 :防止block 在作用域结束之后还没有被调用 就被销毁  放到堆区就可以在作用域结束之后  还可以调用

 

ARC:  

引用外部变量的block 为 __NSMallocBlock__ 类型(堆区block) 申明属性用copy或strong 修饰都可以 系统会自动将栈区block拷到堆区

 

block 引用外部的栈区的局部变量   将该变量从栈区中拷贝一份到堆区中 

block 要改变外部局部变量的值  需要将外部局部变量 用__block修饰

 

面试题:

    __block int i = 10;

    //从栈自动拷贝到堆中,i也被拷贝

    void (^myblock)() = ^{

     NSLog(@"%d",i);        后输出i = 10

    };

    i= 20;

   NSLog(@"----->%d",i);       先输出i = 20

    [self passBlock:myblock];

 

循环引用的问题:

 当 block 对当前控制器 强引用  控制器也对block强引用时  需要将控制器用  __weak修饰  防止循环引用的问题

 

总结:

关于block内存管理,当block内部没有引用外部变量时,block存放在全局区,也就是NSGlobalBlock;在MRC下,当block内部引用外部变量时,block存放在栈区,也就是NSStackBlock;当对该栈区的block进行copy操作时,block将存放在堆区。在ARC下,当block内部引用外部变量时,block存放在堆区;关于堆区与栈区的区别,栈区主要存放局部变量,定义的参数等,在函数结束,系统会自动回收其内存空间,而堆区一般用程序员自行分配释放,若程序员不释放,程序结束时,由系统回收。总的来说,使用栈区更为快捷,而使用堆区更为灵活。

 

blcok的总结