想必很多开发人员知道一般用copy修饰block,接下来就讲解为什么需要用copy,甚至会讲到其实用strong修饰block也是可以的

在 Objective-C 语言中,一共有 3 种类型的 block:

  1. _NSConcreteGlobalBlock 全局的静态 block,不会访问外部局部变量(显然包括无外部变量或者全局变量)。
  2. _NSConcreteStackBlock 保存在栈中的 block,当函数返回时会被销毁。
  3. _NSConcreteMallocBlock 保存在堆中的 block,当引用计数为 0 时会被销毁。

新建一个项目,分别在ARC环境和MRC环境测试一遍

把测试文件改成MRC环境的方法:

把完整的测试代码显示如下:

#import "ViewController.h"

@interface ViewController ()

@property (nonatomic,copy)void(^demoBolck)();

@property (nonatomic,strong)void(^demoBolck1)();

@end

@implementation ViewController

int b=8;//全局变量

- (void)viewDidLoad {

[super viewDidLoad];

void (^demoBolck)() = ^{

NSLog(@"indemoBolck");

};

NSLog(@"demoBolck %@",demoBolck);    //<__NSGlobalBlock__: 0x1085af0e0>  无论ARC还是MRC下,因不访问外部局部(包括无外部变量或者只有全局变量),NSGlobalBlock表示在全局区

void (^demoBolck4)() = ^{

NSLog(@"indemoBolck4  %d",b);

};

NSLog(@"demoBolck4 %@",demoBolck4);    //<__NSGlobalBlock__: 0x10150b120>  全局区

__block int a = 6;   //block内部引用a,并修改其值,需要用block修饰,不然可以不用

void (^demoBolck2)() = ^{

NSLog(@"indemoBolck2 %d",a++);

};

demoBolck2();

NSLog(@"demoBolck2 %@,%d",demoBolck2,a);   //<__NSMallocBlock__: 0x600000056c50> ARC下堆区,在ARC模式下,系统也会默认对Block进行copy操作,Block的内存地址这时候便显示在堆区 <__NSStackBlock__: 0x7fff5d0ada28>MRC下在栈区

NSLog(@"demoBolck2.Copy %@",[demoBolck2 copy]);    //<__NSMallocBlock__: 0x600000056c50>copy操作不管MRC或者ARC都在堆区,只是在MRC下进行copy会改变地址

self.demoBolck = demoBolck2;

NSLog(@"self.demoBolck %@",self.demoBolck);//堆区<__NSMallocBlock__: 0x608000052630>

self.demoBolck1 = demoBolck2;

self.demoBolck1();     //demoBolck2  7   能执行无问题

NSLog(@"self.demoBolck1 %@",self.demoBolck1);     //<__NSMallocBlock__: 0x600000056c50>  strong修饰ARC和MRC都并没有问题, 但是assign和retain在MRC环境下是还是在栈区的,会有问题

}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {

//注意:MRC环境下:demoBolck1用assign,retain修饰,栈区:<__NSStackBlock__: 0x7fff50915a50>,提前释放了所以运行到下面语句程序会崩溃。ARC环境下:用copy,strong, assign, retain修饰是可以正常打印出结果的。 无论什么环境,用copy,strong修饰是可以正常打印出结果的

self.demoBolck1();

}

@end

总结:

  • block内部没有调用外部局部变量时存放在全局区(ARC和MRC下均是)
  • block使用了外部局部变量,这种情况也正是我们平时所常用的方式。MRC:Block的内存地址显示在栈区,栈区的特点就是创建的对象随时可能被销毁,一旦被销毁后续再次调用空对象就可能会造成程序崩溃,在对block进行copy后,block存放在堆区.所以在使用Block属性时使用copy修饰。但是ARC中的Block都会在堆上的,系统会默认对Block进行copy操作
  • 用copy,strong修饰block在ARC和MRC都是可以的,都是在堆区

block的修饰词为什么选用copy的更多相关文章

  1. 属性(@property)的修饰词有哪些,各自是什么作用,在哪种情况下用?

       之前面试了几家公司,都会问到这个基础的问题,以前,没有怎么注意,所以答的很混乱,所以查了查网上的资料,特意整理了一份.   常见修饰词有:assign.weak.strong.retain.co ...

  2. ios 修饰词作用

    copy: NSString\NSMutableString\Block weak: 代理.UI控件(weak) strong: 其他OC对象 assign: 基本数据类型(int\float).枚举 ...

  3. Java基础知识笔记(一:修饰词、向量、哈希表)

    一.Java语言的特点(养成经常查看Java在线帮助文档的习惯) (1)简单性:Java语言是在C和C++计算机语言的基础上进行简化和改进的一种新型计算机语言.它去掉了C和C++最难正确应用的指针和最 ...

  4. Java基础详解 (一)Java的类成员访问权限修饰词(以及类访问权限)

    在一个类的内部,其成员(包括成员变量和成员函数)能否被其他类所访问,取决于该成员的修饰词.Java的类成员访问权限修饰词有四类:private,无(默认情况下),protected和public.其权 ...

  5. OC修饰词 - 内存管理

    <招聘一个靠谱的 iOS>—参考答案(上) 说明:面试题来源是微博@我就叫Sunny怎么了的这篇博文:<招聘一个靠谱的 iOS>,其中共55题,除第一题为纠错题外,其他54道均 ...

  6. Chapter6_访问权限控制_访问权限修饰词

    Java中有四种访问权限,public,private,protected和包访问权限,它们是置于类中每一个成员之前的定义,无论是一个域还是一个方法,下面一一介绍. 一.包访问权限 如果不提供任何访问 ...

  7. 修饰词public、private、protected、默认、四者之间的区别

    在Java语法中,对于类与类中的成员变量和成员方法是通过访问控制符来区分控制的. 下面来看看这四种访问控制符的区别:(public.protected.private.default) 1.publi ...

  8. Java编程思想学习笔记——访问权限修饰词

    几种访问权限修饰词 public,protected,private,friendly(Java中并无该修饰词,即包访问权限,不提供任何访问修饰词) 使用时,放置在类中成员(域或方法)的定义之前的,仅 ...

  9. Django ORM常用的函数以及修饰词

    函数名称或修饰词 说明 filter() 返回符合指定条件的QuerySet exclude() 返回不符合指定条件的QuerySet ordey_by() 串接到QuerySet之后,针对某一指定的 ...

随机推荐

  1. 豹哥嵌入式讲堂:ARM开发中有用的文件(1)- source文件

    大家好,我是豹哥,猎豹的豹,犀利哥的哥.今天豹哥给大家讲的是嵌入式开发里的source文件种类. 众所周知,嵌入式开发属于偏底层的开发,主要编程语言是C和汇编.所以本文要讲的source文件主要指的就 ...

  2. 文件上传之伪Ajax方式上传

    From: <由 Windows Internet Explorer 8 保存> Subject: =?gb2312?B?zsS8/snPtKvWrs6xQWpheLe9yr3Jz7SrI ...

  3. Illustration of Git branching and merge

    网上看到的描述Git工作流程的图片,有些出处忘了保存,仅供学习. 1. One Git Branching Model 出处: http://nvie.com/posts/a-successful-g ...

  4. JMeter集合点

    位置:添加--> 定时器-->Synchronizing Timer     注意:集合点放在所有操作之前.   假设线程组线程数设置的是50个,那么希望50个都准备好一块上,那么集合点中 ...

  5. springBoot系列教程05:fastjson的集成、配置及使用

    springBoot自带的json用着不太习惯,已习惯了fastJSON,下面介绍下fastjson的配置 1. pom引入 <dependency> <groupId>com ...

  6. NOI 2005维护数列

    题目描述 请写一个程序,要求维护一个数列,支持以下 6 种操作:(请注意,格式栏 中的下划线‘ _ ’表示实际输入文件中的空格) 输入输出格式 输入格式: 输入文件的第 1 行包含两个数 N 和 M, ...

  7. Django__RBAC

    RBAC : 基于角色的权限访问控制(Role-Based Access Control) RBAC 模型作为目前最为广泛接受的权限模型 角色访问控制(RBAC)引入了Role的概念,目的是为了隔离U ...

  8. 前端之 CSS🤖

    css (层叠样式表) : 对html标签的渲染和布局 查找 (选择器) 操作标签 (属性操作) 导入用 link 标签,后面的href就用你的文件路径就好 写css文件,要单独写到一个文件里面去 推 ...

  9. 淘宝NPM源的使用

    npm作为国外的node仓库安装工具,自然会受到我大长城防火墙的干扰,国内用户在安装相关的资源的时候,会出现安装失败,以及速度很慢的情况.为了解决npm安装的问题,国内出现了很多npm的镜像网址,ta ...

  10. python导入模块时的执行顺序

    当python导入模块,执行import语句时,到底进行了什么操作?按照python的文档,她执行了如下的操作: 第一步,创建一个新的module对象(它可能包含多个module) 第二步,把这个mo ...