block 知识点整理

2020-05-11  本文已影响0人  化二缺

block 本质

变量捕获

image.png

auto 变量是可能被销毁的,所以auto变量是值传递不是指针传递,才不会产生空指针。static 变量 是一直在内存中的,所以用指针去取地址就行了。

因为作用域不同啊。

会捕获 ,self 是个局部变量


self 是个局部变量 因为是参数.png

会 ,因为_name 相当于 self->_name

类型

 1.  __NSGlobalBlock__ ( _NSConcreteGlobalBlock )
    //这种意义不大 不如写一个函数
 2. __NSStackBlock__ ( _NSConcreteStackBlock )
  //栈的特点是使用后释放,这样再去调用block 有可能出现混乱 所以使用copy 修饰 升级成堆block
 3. __NSMallocBlock__ ( _NSConcreteMallocBlock )
//堆block
  • 1.作为函数返回值
  • 2.将block赋值给__strong指针的时候
  • 3.block作为Cocoa API 中方法名含有usingBlock的方法参数的时候


    image.png
  • 4.GCD的block (不用写weak 他自己是线程安全的)

对象类型的auto变量

  1. 如果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内部无法修改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内部的copy函数
  • copy函数内部会调用 _Block_object_assign函数
  • _Block_object_assign 函数会对 __block变量形成强引用(retain)
  • 这里只是在ARC情况下,MRC不会retain
    image.png
  • 会调用block内部的dispose函数
  • dispose函数内部hi调用 _Block_object_dispose函数
  • _Block_object_dispose函数会自己释放引用的 __block变量(release)

__block的 __forwarding指针

image.png

循环引用

老生常谈 巴拉巴拉。。。

__unsafe_unretained :不安全弱引用

__unsafe_unretained__weak的区别

weak会置空指针
__unsafe_unretained 不会 ,指针仍然指向,可能会出现野指针问题

不需要
没有修改指针 只是修改了数组内容,所以不用

上一篇下一篇

猜你喜欢

热点阅读