iOS Block笔记总结
前言:
对block的简单笔记总结,
1.本质:
封装了函数调用和函数调用环境的对象
2.block结构:
3.block捕获变量:
由于需要跨函数访问变量,所以需要捕获变量,(防止访问时已被销毁)
- auto变量(基本数据类型):值捕获,超出作用域就被销毁了
- static变量:指针捕获,
- 全局变量:直接访问
- self,也属于局部变量,(每个方法默认参数(self,_cmd))
4.block类型:
block类型 |
环境 |
copy |
存储区域 |
NSGlobalBlock |
没有访问auto变量 |
什么也不做 |
程序的数据区域 .data |
NSStackBlock |
访问auto变量 |
从栈赋值到堆上 |
栈 |
NSMallocBlock |
NSStackBlock 调用copy |
引用计数+1 |
堆 |
5.block 的copy:
在ARC环境下,编译器会根据情况自动将栈上的block复制到堆上,比如以下情况:
- Block 作为函数的返回值
- 将block赋值给__strong指针时
- block 作为Cocoa API中方法名含有usingBlock的方法参数
- block作为GCD API的方法参数
6.block内部访问对象类型的auto变量:
当block内部访问了对象类型的auto变量时,
- 如果block是在栈上,将不会对auto变量进行强引用
- 如果block 被拷贝到堆上
- 会调用block内部的copy函数,
- copy函数内部调用 _Block_objct_assgin函数,
- _Block_objct_assgin函数会根据auto变量的修饰符(__strong,__weak,__unsafe_unretained)做出对应的操作,类似retain(强引用、弱应用)
如果block从堆上移除
- 会调用block中的dispose函数
- dispose函数内部调用_Block_objct_dispose函数
- _Block_object_dispose函数会自动释放引用的auto变量,类似于release
7.__block 修饰符
编译器会将__block修饰的变量包装成一个对象
- __block 可以用于解决block内部无法修改auto变量值的问题
- __block不能修饰 static、全局变量
- 当block在栈上是,并不会对__block对象强引用
- 如果block 被拷贝到堆上,对__block对象是强引用
- 当block被copy到堆上时,会调用block(desc)中的copy函数
- copy函数内部调用 _Block_objct_assgin函数,
- _Block_objct_assgin函数会对__block变量进行强引用(retain)
- 如果是对象类型时,在__block变量中也会存在 内存管理函数(copy,dispose)
- 当__block变量在栈中,不会对指向的对象产生强引用
- 当__block变量被copy到堆时,会调用__block中的copy函数,
- copy函数内部调用__Block_objct_assgin函数,该函数会根据对象的修饰符(__strong,__weak,__unsafe_unretained)做出对应的操作,类似retain(强引用、弱应用)(注意:仅限于ARC时会retain,MRC下不会retain)。
如果block变量从堆上移除
- 会调用block中的dispose函数
- dispose函数内部调用_Block_objct_dispose函数
- _Block_object_dispose函数会自动释放引用的__block变量,类似于release
如果是对象类型时,也会调用
- 会调用__block中的dispose函数
- dispose函数内部调用_Block_objct_dispose函数
- _Block_object_dispose函数会自动释放引用的auto变量,类似于release
注意:当block内部对应__block对象都是强引用,
struct __Block_byref_p_0 { // 包装成的结构体对象
void *__isa;
__Block_byref_p_0 *__forwarding;
int __flags;
int __size;
void (*__Block_byref_id_object_copy)(void*, void*);
void (*__Block_byref_id_object_dispose)(void*);
Person *p;
};
struct __main_block_impl_0 {
struct __block_impl impl;
struct __main_block_desc_0* Desc;
__Block_byref_p_0 *p; // by ref 指向包装成的g结构体对象指针
__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, __Block_byref_p_0 *_p, int flags=0) : p(_p->__forwarding) {
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
};
static struct __main_block_desc_0 {
size_t reserved;
size_t Block_size;
void (*copy)(struct __main_block_impl_0*, struct __main_block_impl_0*);
void (*dispose)(struct __main_block_impl_0*);
}
结构:
8.__block 结构体对象内部的__forwarding指针
9.循环引用问题:
ARC:
__weak,
__unsafe_unreatined,不会产生强引用,不安全,缺点:对象销毁后,指针不会自动指向nil
__block,缺点:必须手动调用执行block,并在block中把对象赋值nil,
MRC:
__unsafe_unretained
__block block内不会进行retain操作


iOS Block笔记总结的更多相关文章
- iOS学习笔记之ARC内存管理
iOS学习笔记之ARC内存管理 写在前面 ARC(Automatic Reference Counting),自动引用计数,是iOS中采用的一种内存管理方式. 指针变量与对象所有权 指针变量暗含了对其 ...
- iOS回顾笔记( 01 )
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...
- iOS回顾笔记( 02 ) -- 由九宫格布局引发的一系列“惨案”
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...
- iOS回顾笔记(04) -- UIScrollView的基本使用详解
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...
- iOS回顾笔记(05) -- 手把手教你封装一个广告轮播图框架
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...
- iOS回顾笔记(06) -- AutoLayout从入门到精通
iOS回顾笔记(06) -- AutoLayout从入门到精通 随着iOS设备屏幕尺寸的增多,当下无论是纯代码开发还是Xib/StoryBoard开发,自动布局已经是必备的开发技能了. 我使用自动布局 ...
- iOS回顾笔记(07) -- UITableView的使用和性能优化
iOS回顾笔记(07) -- UITableView的使用和性能优化 如果问iOS中最重要的最常用的UI控件是什么,我觉得UITableView当之无愧!似乎所有常规APP都使用到了UITableVi ...
- iOS回顾笔记(08) -- 自定义Cell的类型和创建步骤总结
iOS回顾笔记(08) -- 自定义Cell的类型和创建步骤总结 项目中我们常见的自定义cell主要分为两种 等高cell:如应用列表.功能列表 非等高cell:如微博列表.QQ聊天页面 下面对这 ...
- iOS回顾笔记(09) -- Cell的添加、删除、更新、批量操作
iOS回顾笔记(09) -- Cell的添加.删除.更新.批量操作 项目中经常有对UITableViewCell做各种操作的需求: 添加一个新的cell 删除某行cell 刷新cell上某行数据(如修 ...
- IOS学习笔记48--一些常见的IOS知识点+面试题
IOS学习笔记48--一些常见的IOS知识点+面试题 1.堆和栈什么区别? 答:管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制:对于堆来说,释放工作由程序员控制,容易产生memor ...
随机推荐
- C 语言版线程池
一.初始线程池 1.1 何为线程池? 我们先来打个比方,线程池就好像一个工具箱,我们每次需要拧螺丝的时候都要从工具箱里面取出一个螺丝刀来.有时候需要取出一个来拧,有时候螺丝多的时候需要多个人取出多个来 ...
- Redis - 数据类型映射底层结构
简介 从数据类型上体现就是,同一个数据类型,在不同的情况下会使用不同的编码类型,底层所使用的的数据结构也不相同. 字符串对象 字符串对象的编码可以是 int.raw 和 embstr 三者之一. em ...
- X配置文件xorg.conf分析
X配置文件xorg.conf分析 转载于:http://blog.csdn.NET/comcat/archive/2007/04/02/1549658.aspx 作者:壮志凌云的csdn博客 X的配置 ...
- 【Azure 存储服务】Java Storage SDK 调用 uploadWithResponse 代码示例(询问ChatGTP得代码原型后人力验证)
问题描述 查看Java Storage SDK,想找一个 uploadWithResponse 的示例代码,但是通过全网搜索,结果没有任何有帮助的代码.使用最近ChatGPT来寻求答案,得到非常有格 ...
- Llinux系统(Centos/Ubuntu/Debian)弹性云系统盘扩容方法
警告: 1.调整过分区管理方式的,例如lvm管理方式,请忽略此教程. 2.ubuntu18系统暂不支持脚本扩容,请手动扩容,参看下面ubuntu18部分,用parted操作 脚本自动处理(推荐) SS ...
- Git&GitHub简介与入手(一)
一.Git版本控制 1.集中式版本控制工具:SVN(版本控制集中在服务器端,会有单点故障风险): 2.分布式版本控制工具:Git: 3.Git简史 Talk is cheap, show me the ...
- 2020-12-01:java中,什么是安全点和安全区域?
福哥答案2020-12-04: 安全点用户线程暂停,GC 线程要开始工作,但是要确保用户线程暂停的这行字节码指令是不会导致引用关系的变化.所以 JVM 会在字节码指令中,选一些指令,作为"安 ...
- 2021-08-16:回文对。给定一组 互不相同 的单词, 找出所有 不同 的索引对 (i, j),使得列表中的两个单词, words[i] + words[j] ,可拼接成回文串。
2021-08-16:回文对.给定一组 互不相同 的单词, 找出所有 不同 的索引对 (i, j),使得列表中的两个单词, words[i] + words[j] ,可拼接成回文串. 福大大 答案20 ...
- SpringBoot 使用 Sa-Token 完成注解鉴权功能
注解鉴权 -- 优雅的将鉴权与业务代码分离.本篇我们将介绍在 Sa-Token 中如何通过注解完成权限校验. Sa-Token 是一个轻量级 java 权限认证框架,主要解决登录认证.权限认证.单点登 ...
- Django4全栈进阶之路19 项目实战(用户管理):user_delete.html用户删除画面设计
1.user_list.html删除按钮链接设置: <td> <a class="btn btn-danger btn-xs" href="{% url ...

