美文网首页
block的本质

block的本质

作者: AlwaysBlue | 来源:发表于2020-05-06 12:03 被阅读0次

1.block的原理是怎样的?本质是什么?
block本质上也是一个OC对象,他内部也有一个isa指针。block是封装了函数调用以及函数调用环境的OC对象。

没有__block时,普通类型和对象类型的区分;有__block时,会为普通类型和对象类型再单独生成对应的struct结构。

2.__block的作用是什么?有什么使用注意点?
外部属性修饰符:auto:局部变量。block结构体中会专门增加一个参数来存储变量的值。
static:

值传递就是在block的结构体中有一个相同的变量;static修饰的变量是指针传递,编译出来的c++是&引用

https://juejin.im/post/5b0181e15188254270643e88
在文章中的例子:全局变量或者静态全局变量,在生成的C++代码中是没有那两个参数的。在block中是直接访问的,是因为存储的地点就是你可以访问的。如果是局部变量,需要跨函数(block相当于是个函数)

当block中捕获对象类型的变量时,我们发现block结构体__main_block_impl_0的描述结构体__main_block_desc_0中多了两个参数copy和dispose函数

_Block_object_assign函数调用时机及作用

当block进行copy操作的时候就会自动调用__main_block_desc_0内部的__main_block_copy_0函数,__main_block_copy_0函数内部会调用_Block_object_assign函数。

_Block_object_assign函数会自动根据__main_block_impl_0结构体内部的person是什么类型的指针,对person对象产生强引用或者弱引用。可以理解为_Block_object_assign函数内部会对person进行引用计数器的操作,如果__main_block_impl_0结构体内person指针是__strong类型,则为强引用,引用计数+1,如果__main_block_impl_0结构体内person指针是__weak类型,则为弱引用,引用计数不变

_Block_object_dispose函数调用时机及作用

当block从堆中移除时就会自动调用__main_block_desc_0中的__main_block_dispose_0函数,__main_block_dispose_0函数内部会调用_Block_object_dispose函数。

_Block_object_dispose会对person对象做释放操作,类似于release,也就是断开对person对象的引用,而person究竟是否被释放还是取决于person对象自己的引用计数。

总结
一旦block中捕获的变量为对象类型,block结构体中的__main_block_desc_0会出两个参数copy和dispose因为访问的是个对象,block希望拥有这个对象,就需要对对象进行引用,也就是进行内存管理的操作。比如说对对象进行retarn操作,因此一旦block捕获的变量是对象类型就会会自动生成copy和dispose来对内部引用的对象进行内存管理。

当block内部访问了对象类型的auto变量时,如果block是在栈上,block内部不会对person产生强引用。不论block结构体内部的变量是__strong修饰还是__weak修饰,都不会对变量产生强引用。(MRC还是ARC?应该不论在什么环境下都是,因为

如果block被拷贝到堆上。copy函数会调用_Block_object_assign函数,根据auto变量的修饰符(__strong,__weak,unsafe_unretained)做出相应的操作,形成强引用或者弱引用

如果block从堆中移除,dispose函数会调用_Block_object_dispose函数,自动释放引用的auto变量。

不论对象方法还是类方法都会默认将self作为参数传递给方法内部,既然是作为参数传入,那么self肯定是局部变量。参数就是局部变量。局部变量肯定会被block捕获。

访问了局部变量的block,在MRC中是NSStackBlock类型,在ARC中则是NSMallocBlock类型。
在ARC中,属性为assign和weak的block是NSStackBlock类型,
在ARC中,https://www.jianshu.com/p/19e6de8437f5 这篇文章更清晰,但是里面的NSGlobalBlock到底是放到了代码段还是数据段?
weak当对象为空时,会设置为nil;unsafe_unretained不会,但也是弱引用

block的属性修饰词为什么是copy?使用block有哪些使用注意?

block在修改NSMutableArray,需不需要添加__block?
不需要, NSMutableArray是通过地址传入的。就跟静态变量一样,static,传入的是指针,并没有用__block修饰。可以改变对象的内容,但是如果是改变的对象的地址,则是不允许的,必须使用__block.

ARC会在哪些情况下,自动对block进行一次copy操作?
1. block作为函数返回值时
2. 将block赋值给__strong指针时(可以用来对比属性的assign和weak)
3. block作为Cocoa API中方法名含有usingBlock的方法参数时
4. block作为GCD API的方法参数时

---------------------------------------------------
为什么要通过__forwarding获取age变量的值???
到此为止,__block为什么能修改变量的值已经很清晰了。__block将变量包装成对象,然后在把age封装在结构体里面,block内部存储的变量为结构体指针,也就可以通过指针找到内存地址进而修改变量的值。

__forwarding是指向自己的指针。这样的做法是为了方便内存管理,之后内存管理章节会详细解释。

在main函数中,直接创建了和__block相关的结构。

相关文章

  • Block总结

    一、Block的底层结构及本质 (1)block本质: 从代码可以看出,Block的本质就是NSObject. 也...

  • OC底层原理(八):Block

    block是经常使用的一种技术,那么block的本质是什么呢? Block的本质 block本质上也是OC对象,它...

  • 理清 Block 底层结构及其捕获行为

    来自掘金 《理清 Block 底层结构及其捕获行为》 Block 的本质 本质 Block 的本质是一个 Obje...

  • Block详解-小码哥

    block本质 block的本质是封装了函数调用和函数调用环境的OC对象。 block结构 Block_layou...

  • iOS-底层原理28:block底层原理

    本文主要介绍:1、block的本质2、block捕获变量3、block的类型4、__block原理 本质 通过cl...

  • block系列文章总结

    iOS源码解析:Block的本质<一>iOS源码解析:Block的本质<二>Objective C block背后...

  • Block详解

    block的本质 先看block的简单实现 转为C++代码 查看Block的继承关系 结论: block本质上也是...

  • 2019 知识点总结

    1、Block 释放 追问 (1)Block本质? Block本质就是一个OC对象,内部有isa指针。 Block...

  • 06-OC中block的底层原理

    06-block的本质 在讲解block的底层原理前,我们先抛出如下block相关的问题: block的本质,底层...

  • iOS Block详解

    第一部分:Block本质 Q:什么是Block,Block的本质是什么? block本质上也是一个OC对象,它内部...

网友评论

      本文标题:block的本质

      本文链接:https://www.haomeiwen.com/subject/heuuwhtx.html