Block 底层值__Block修饰符
__Block 修饰符
Block 想要改变外部的变量,必须要用__Block 来修饰自动变量。
根据内存地址可以看出来,__block 所修饰的变量,将外部的变量在栈中的内存地址放到了堆中。
// auto 自动变量的内存分配在栈区域 stack__block int meters = 1000;// 在block 引用之前 0x7ffeefbff4f8NSLog(@"在block 引用之前 %p",&meters);// 3 无返回值无参数void (^Run1)(void) = ^{meters = 2000;// 在block 引用之后 0x100502ac8NSLog(@"在block 引用之后 %p",&meters);NSLog(@"i have run %d meters",meters);} ;Run1();
转为C++ 代码 看出
meter 是如何改变的
先是找到 __forwarding 结构体,然后的话再去找打结构体内部的meter 属性
(meters->__forwarding->meters) = 2000;
struct __main_block_impl_0 {struct __block_impl impl;struct __main_block_desc_0* Desc;__Block_byref_meters_0 *meters; // by ref__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, __Block_byref_meters_0 *_meters, int flags=0) : meters(_meters->__forwarding) {impl.isa = &_NSConcreteStackBlock;impl.Flags = flags;impl.FuncPtr = fp;Desc = desc;}
};// meter 包装成一个对象,里面是含有一个isa 指针的
struct __Block_byref_meters_0 {void *__isa;
__Block_byref_meters_0 *__forwarding;int __flags;int __size;int meters;
};//meter 是如何改变的static void __main_block_func_0(struct __main_block_impl_0 *__cself) {__Block_byref_meters_0 *meters = __cself->meters; // bound by ref(meters->__forwarding->meters) = 2000;}
1 在ARC 环境下,Block 被引用的时候,会被Copy 一次,由栈区Copy 到堆区域
2 在Block 被Copy的时候,Block 内部的变量也会被copy 一份到堆上面
3 被__Block 修饰的变量,在被Block 引用的时候,会变成结构体也就是OC的对象,里面的————forwarding 指针由栈copy 到堆上面
4 栈上__block 变量结构体中,__forwarding的指针指向堆上面__block 变量结构体,堆上的__block 变量结构体中的
__forwarding 指针指向自己
5 当block 从堆中移除的时候,会调用block 内部的dispose 函数,dispose函数内部会调用_Block_object_dispose函数,_Block_object_dispose函数会自动释放引用的__block变量(release)
图片
Block 底层值__Block修饰符相关推荐
- Block截获自动变量实现与__block修饰符内部实现
Block自动截获变量 在Block中访问一个外部的局部变量,Block会持用它的临时状态,外部局部变量的变化不会影响它的的状态. eg: typedef void(^WxsBlock) ();- ( ...
- java重写——返回值、修饰符
返回值类型: 在java5或者以前,必须一样.java7.java8可以不同,但必须是父类返回值的派生类 修饰符: 子类重写父类的方法访问修饰,不能低于父类的方法访问修饰权限.
- ios Block底层详解、框架结构:捕获、对象类型、__block、__forwarding、循环引用
1:捕获 2:block类型 2.1:问题 :mrc环境下 下面讲的都是mrc环境下,会真实很多 2.2:在arc下,block 自动加上copy的情况---:返回block. 2.3:在arc下, ...
- __block和__weak修饰符的区别
block下循环引用的问题 __block本身并不能避免循环引用,避免循环引用需要在block内部把__block修饰的obj置为nil __weak可以避免循环引用,但是其会导致外部对象释放了之后, ...
- 7 类与对象,方法和函数的定义和使用,返回值,权限修饰符 public default protected private(重点)
文章目录 1 面向对象 1 面向对象概述 2 类与对象 2.1 概述 2.2 Java中类的定义万物皆对象. 2.3Java中对象的定义和使用 3 方法和函数的定义和使用 3.1 什么是方法,函数 3 ...
- Java学习系列(四)Java面向对象之修饰符、封装、继承、多态详解
今天内容比较多,直接步入正题吧. 类和对象的定义 类是现实世界或思维世界中的实体在计算机中的反映,它将数据以及这些数据上的操作封装在一起.而对象是具有类类型的变量,存在于堆内存中.类是对象的抽象,而对 ...
- Java面向对象之修饰符、封装、继承、多态详解
类和对象的定义 类是现实世界或思维世界中的实体在计算机中的反映,它将数据以及这些数据上的操作封装在一起.而对象是具有类类型的变量,存在于堆内存中.类是对象的抽象,而对象是类的具体实例.类是抽象的,不占 ...
- 深入浅出OOP(五): C#访问修饰符(Public/Private/Protected/Internal/Sealed/Constants)
访问修饰符(或者叫访问控制符)是面向对象语言的特性之一,用于对类.类成员函数.类成员变量进行访问控制.同时,访问控制符也是语法保留关键字,用于封装组件. Public, Private, Protec ...
- vue与elementUI中给el-input绑定键盘按键--按键修饰符
vue怎么写键盘事件 vue允许将按键值作为修饰符来使用,如监听回车事件,有两种写法,如下代码: <input type="text" @keyup.13="con ...
最新文章
- linux c warning: implicit declaration of function 'strtok_r'解决方案
- ios14的蓝牙弹窗_iOS14来了,总结一下给你带来了哪些最实用的功能
- spring 配置文件模板
- 磁盘的磁道(Track)
- 纽曼皮尔逊准则Matlab实现,纽曼-皮尔逊准则,Neyman Pearson Criterion,在线英语词典,英文翻译,专业英语...
- [转载] Python中pass的作用
- 新版《谷歌搜索引擎优化初学者指南》
- MySQL -- 行转列 -- GROUP_CONCAT -- MAX(CASE WHEN THEN)
- command -- 把动作封装成类
- 【转】SVN中的Branches分支以及Tags标签详解与应用举例
- c#中接口的使用方法图解_C#中的接口interface的使用
- 李宏毅机器学习笔记【未完】
- 电商后台管理系统项目介绍和项目初始化
- 学信号处理要理解均值、平均偏差、标准差、方差
- dhcp服务器自动分配dns,一文了解如何使用DHCP自动分配IP地址?
- 理解 this.initialize.apply ( this, arguments )
- 峰值帧+时序信息 跨数据集微表情识别
- 本世纪,佛祖派机器人来弘扬佛法
- mysql查询每行重复_MySQL查询返回重复的行
- 12、python 海龟绘图 turtle