block的修饰词为什么选用copy
想必很多开发人员知道一般用copy修饰block,接下来就讲解为什么需要用copy,甚至会讲到其实用strong修饰block也是可以的
在 Objective-C 语言中,一共有 3 种类型的 block:
- _NSConcreteGlobalBlock 全局的静态 block,不会访问外部局部变量(显然包括无外部变量或者全局变量)。
- _NSConcreteStackBlock 保存在栈中的 block,当函数返回时会被销毁。
- _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的更多相关文章
- 属性(@property)的修饰词有哪些,各自是什么作用,在哪种情况下用?
之前面试了几家公司,都会问到这个基础的问题,以前,没有怎么注意,所以答的很混乱,所以查了查网上的资料,特意整理了一份. 常见修饰词有:assign.weak.strong.retain.co ...
- ios 修饰词作用
copy: NSString\NSMutableString\Block weak: 代理.UI控件(weak) strong: 其他OC对象 assign: 基本数据类型(int\float).枚举 ...
- Java基础知识笔记(一:修饰词、向量、哈希表)
一.Java语言的特点(养成经常查看Java在线帮助文档的习惯) (1)简单性:Java语言是在C和C++计算机语言的基础上进行简化和改进的一种新型计算机语言.它去掉了C和C++最难正确应用的指针和最 ...
- Java基础详解 (一)Java的类成员访问权限修饰词(以及类访问权限)
在一个类的内部,其成员(包括成员变量和成员函数)能否被其他类所访问,取决于该成员的修饰词.Java的类成员访问权限修饰词有四类:private,无(默认情况下),protected和public.其权 ...
- OC修饰词 - 内存管理
<招聘一个靠谱的 iOS>—参考答案(上) 说明:面试题来源是微博@我就叫Sunny怎么了的这篇博文:<招聘一个靠谱的 iOS>,其中共55题,除第一题为纠错题外,其他54道均 ...
- Chapter6_访问权限控制_访问权限修饰词
Java中有四种访问权限,public,private,protected和包访问权限,它们是置于类中每一个成员之前的定义,无论是一个域还是一个方法,下面一一介绍. 一.包访问权限 如果不提供任何访问 ...
- 修饰词public、private、protected、默认、四者之间的区别
在Java语法中,对于类与类中的成员变量和成员方法是通过访问控制符来区分控制的. 下面来看看这四种访问控制符的区别:(public.protected.private.default) 1.publi ...
- Java编程思想学习笔记——访问权限修饰词
几种访问权限修饰词 public,protected,private,friendly(Java中并无该修饰词,即包访问权限,不提供任何访问修饰词) 使用时,放置在类中成员(域或方法)的定义之前的,仅 ...
- Django ORM常用的函数以及修饰词
函数名称或修饰词 说明 filter() 返回符合指定条件的QuerySet exclude() 返回不符合指定条件的QuerySet ordey_by() 串接到QuerySet之后,针对某一指定的 ...
随机推荐
- 3.Nginx常用功能介绍
Nginx常用功能介绍 Nginx反向代理应用实例 反向代理(Reverse Proxy)方式是指通过代理服务器来接受Internet上的连接请求,然后将请求转发给内部网络上的服务器,并且从内部网络服 ...
- python (5分钟实现一个游戏的屏蔽敏感字系统,)
import datetime time=datetime.datetime.now() dirty= ['fuck','狗日的','犊子','麻批','仙人板板','R你妈','操你','草你',' ...
- Struts2-整理笔记(四)Action生命周期、如何获取参数(3种)、集合类型参数封装
一.Action生命周期 每次请求到来时,都会创建一个新的Action实例 Action是线程安全的,可以使用成员变量接收参数 二.获取参数的方式(3种) 1.属性驱动获得参数 每次请求Action时 ...
- 任务调度 -----> quartz 不同时间间隔调度任务
Quartz Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用.Quartz可以用来创建简单或为运 ...
- css挖坑爬坑之div高宽相等
目标效果 对于这么一个头像,外面是一个圆角的div里面是一个img,对于外面的div我要使他高度等于宽度. 发现问题 开始的时候设置宽度为100%然后高度为100%,这样子对于宽度来说的话可以撑满页面 ...
- ASP.NET Core学习之二 菜鸟踩坑
对于像我这样没接触过core的人,坑还是比较多的,一些基础配置和以前差别很大,这里做下记录 一.Startup 1.注册服务 // This method gets called by the run ...
- 该帐户当前被锁定,所以用户sa登录失败。系统管理员无法将该帐户解锁
运行程序时抛出异常: 基础提供程序在 Open 上失败,详细信息:该帐户当前被锁定,所以用户sa登录失败.系统管理员无法将该帐户解锁. 1.考虑连接字符串是否正常 登录数据库,发现登录报同样的错误 = ...
- Class StatusesTableSeeder does not exist 如何解决
Class StatusesTableSeeder does not exist错误如何解决 Laravel 5.* 执行seeder命令出现错误的解决方法 最近在使用Laravel开发一个项 ...
- JS中闭包、函数与对象的介绍和用法
闭包 闭包概念:当一个内部函数被调用,就会形成闭包,闭包就是能够读取其他函数内部变量的函数,定义在一个函数内部的函,创建一个闭包环境,让返回的这个子程序抓住i,以便在后续执行时可以保持对这个i的引用. ...
- hadoop+hive+spark搭建(一)
1.准备三台虚拟机 2.hadoop+hive+spark+java软件包 传送门:Hadoop官网 Hive官网 Spark官网 一.修改主机名,hosts文件 主机名修改 hostnam ...