block 知识点整理
2020-05-11 本文已影响0人
化二缺
block 本质
- block 本质上也是一个oc对象,它内部也有一个isa指针
- block是封装了函数调用以及函数调用环境的OC 对象
- image.png
变量捕获
image.png- 为什么 auto 和 static 变量不一样?
auto 变量是可能被销毁的,所以auto变量是值传递不是指针传递,才不会产生空指针。static 变量 是一直在内存中的,所以用指针去取地址就行了。
- 为什么局部变量需要捕获,而全局变量不需要?
因为作用域不同啊。
- 会不会捕获self,为什么?
会捕获 ,self 是个局部变量
self 是个局部变量 因为是参数.png
- 会不会捕获 _name,为什么?
会 ,因为_name 相当于 self->_name
类型
- block 有3种类型,可以通过调用class方法或者isa指针查看具体类型,最终都是继承自 NSBlock类型
1. __NSGlobalBlock__ ( _NSConcreteGlobalBlock )
//这种意义不大 不如写一个函数
2. __NSStackBlock__ ( _NSConcreteStackBlock )
//栈的特点是使用后释放,这样再去调用block 有可能出现混乱 所以使用copy 修饰 升级成堆block
3. __NSMallocBlock__ ( _NSConcreteMallocBlock )
//堆block
-
block内存地址所在
image.png -
block分类型的原因
image.png -
每一种类型的block 调用copy后的结果如下图
image.png -
ARC环境下,编译器会依据情况自动将栈上的block复制到堆上
- 1.作为函数返回值
- 2.将block赋值给__strong指针的时候
3.block作为Cocoa API 中方法名含有usingBlock的方法参数的时候
image.png- 4.GCD的block (不用写weak 他自己是线程安全的)
对象类型的auto变量
- 当block内部访问了对象类型的auto变量时候
- 如果block是在栈上,将不会对auto变量产生强引用
2.如果block被拷贝到堆上
- 会调用block内部的copy函数
- copy函数内部会调用 _Block_object_assign函数
- _Block_object_assign函数会根据auto变量的修饰符(__strong、__weak、__unsafe_unretained)做出相应的操作。类似retain (形成强引用,弱引用)
3.如果block从堆上移除
- 会调用block内部的 dispose函数
- dispose函数内部会调用_Block_object_dispose函数
- _Block_object_dispose函数会自动释放引用的auto变量,类似于release
__block 关键字 (能不用就不用)
- __block的作用
- __block可以用于解决block内部无法修改auto变量值的问题
- __block不能修饰全局变量、静态变量(static)
- 编译器会将__block修饰的参数 变成一个对象
__block包装实例1.png
__block包装实例2.png
- __block 细节 :age的地址直接输出 和 __block封装的结构体内部的age结构体地址是一样的,这样做的意义在于屏蔽内部实现。比较符合直觉。
__weak 问题
在使用clang转换OC 为C++代码时候,可能会遇到以下问题
cannot create __weak reference in file using manual reference
解决方案 : 支持 ARC 指定运行时系统版本
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc - fobjc-runtime=iOS-13.0.0 main.m
__block 内存管理
-
block 是在栈上的时候是不会对 __block 变量产生强引用
-
block 被拷贝到堆的时候
- 会调用block内部的copy函数
- copy函数内部会调用 _Block_object_assign函数
- _Block_object_assign 函数会对 __block变量形成强引用(retain)
这里只是在ARC情况下,MRC不会retain
image.png
- block从堆中移除时
- 会调用block内部的dispose函数
- dispose函数内部hi调用 _Block_object_dispose函数
- _Block_object_dispose函数会自己释放引用的 __block变量(release)
__block的 __forwarding指针
image.png循环引用
老生常谈 巴拉巴拉。。。
__unsafe_unretained :不安全弱引用
__unsafe_unretained 和 __weak的区别
weak会置空指针
__unsafe_unretained 不会 ,指针仍然指向,可能会出现野指针问题
- block在修改 NSMutableArray 需不需要添加__block?
不需要
没有修改指针 只是修改了数组内容,所以不用