您好,欢迎来到二三娱乐。
搜索
您的当前位置:首页Block 内存管理(MRC)

Block 内存管理(MRC)

来源:二三娱乐

在说Block内存管理之前,先提个问题,Block是不是一个对象?

Block是一个对象

为什么呢?苹果官方文档给出了答案

image1
具体解释链接
Block内存管理分为MRC何ARC, 此篇文章介绍Block在MRC环境下的内存管理。
  • 当我们打开一个工程文件时,如何判断当前项目是ARC或者MRC呢?
    1、在dealloc 方法中看是否能调用super, 只有在MRC环境下才能调用super。
    2、能否可以使用retain,release,如果可以使用就是MRC。

  • MRC开发了解常识
    1、MRC没有strong weak,局部变量对象相当于基本数据类型。
    2、MRC给成员属性赋值,一定要调用setter方法,不能直接访问实例变量来赋值。(调用setter方法,会做很多事情,否则会造成内存泄漏)

言归正传,下面介绍MRC环境下Block的内存管理。

1、新建工程,默认ARC环境,设置为MRC环境。

Image2.png

2、定义一个block

  • Block 没有引用局部变量

    void(^block)(void) = ^{    
    };
    NSLog(@"%@", block);
    

打印结果为:

    <__NSGlobalBlock__: 0x106350088>

由此可以看出此时Block放在全局区

  • Block 引用局部变量

     NSInteger index = 0;
     void(^block)(void) = ^{
      NSLog(@"%ld", index);
      };
     NSLog(@"%@", block);
    

打印结果为:

    <__NSStackBlock__: 0x7ffee143fa28>

由此可以看出此时Block放在栈区

  • Block 引用静态变量

     static NSInteger index = 0;
     void(^block)(void) = ^{
      NSLog(@"%ld", index);
      };
     NSLog(@"%@", block);
    

打印结果为:

    <__NSGlobalBlock__: 0x10136b070>

由此可以看出此时Block放在全局区

  • Block 引用全局变量

     NSInteger a = 0;//全局变量
    
    
     void(^block)(void) = ^{
      NSLog(@"%ld", a);
      };
     NSLog(@"%@", block);
    

打印结果为:

    <__NSGlobalBlock__: 0x104905070>

由此可以看出此时Block放在全局区

3、定义属性保存Block

@property (nonatomic, retain) void(^block)(void);

int a = 0;
void(^block)(void) = ^{
    NSLog(@"%d", a);
};
self.block = block;
NSLog(@"%@", self.block);

打印结果为:

<__NSStackBlock__: 0x7ffeedd1da28>

此时再去访问self.block, 就会出现崩溃


image3.png

使用retain修饰block,此时block还在栈里

总结

只要block没有引用外部局部变量,block放在全局区
只要Block引用外部局部变量,block放在栈里面.
block只能使用copy,不能使用retain

Copyright © 2019- yule263.com 版权所有 湘ICP备2023023988号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务