想必很多开发人员知道一般用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. lesson - 6 课程笔记

    一.df  作用:  显示磁盘分区上的可使用的磁盘空间, 默认显示单位为kb . 可以利用该命令来获取硬盘被占用了多少空间,目前还剩下多少空间的等信息. 选项: -a :包含全部的文件系统 -h :以 ...

  2. 7.nginx伪静态规则

    网上收集的一些常用的,要用的时候就仿照一下,或直接拿来用. WordPress伪静态规则 location / { index index.html index.php; if (-f $reques ...

  3. java 类的继承和接口的继承

    父类 public class person { String name; int age; void eat(){ System.out.println("吃饭"); } voi ...

  4. 【liferay】2、可配置portlet

    定义:edit和config模式一般没有使用,对于使用editor和config等模式的portlet,我们可以将他们称为可配置portlet. 我们先新建一个portlet项 添加可配置的控制元素, ...

  5. 阿里maven仓库地址 和 oschina maven仓库地址

    <mirror>     <id>nexus-aliyun</id>     <mirrorOf>*</mirrorOf>     < ...

  6. .Net程序员学用Oracle系列:视图、函数、存储过程、包

    1.视图 在实际操作过程中,本人发现 Oracle 视图定义有一个缺陷,就是不大方便注释,每次写好的注释执行之后再打开视图定义所有注释就全都没了.后来我发现把注释写到末尾就不会被清除,但这样总感觉乖乖 ...

  7. 企业信息化快速开发平台--JeeSite

    JeeSite是在Spring Framework基础上搭建的一个Java基础开发平台,以Spring MVC为模型视图控制器,MyBatis为数据访问层, Apache Shiro为权限授权层,Eh ...

  8. Jquery_基础(二) 包装集

    包装集 <body> <div id="a01">1.包装集——length</div> <div id="a02"& ...

  9. CSS 换行问题white-space属性 window对象和global对象

    white-space: nowrap禁止换行 1.word-wrap:break-word; 内容将在边界内换行,仅用于块对象,内联对象要用的话,必须要设定height.width或display: ...

  10. Java入门篇(二)——Java语言基础(下)

    上篇说到Java中的变量与常量,接下来就是简单的计算了,首先需要了解一下Java中的运算符. 六.运算符 1. 赋值运算符 赋值运算符即"=",是一个二元运算符(即对两个操作数进行 ...