Block的底层原理

简介: block-> 全局区;block -> 访问外界变量(copy) -> 强引用 -> 堆区;-> _weak可弱引用 -> 栈区
  • NSGlobalBlock_(全局block) -> 无参,无返回值 ->全局区 ->0x1开头
  • NSMallocBlock_(堆区block) -> 函数, 对象, 访问外界 -> 0x6开头
  • NSStackBlock(栈区block) -> 内有局部变量,  局部变量没有拷贝前 -> 栈区 ->拷贝后 ->堆区 -> 0x7开头


总结:


block-> 全局区

block -> 访问外界变量(copy) -> 强引用 -> 堆区

-> _weak可弱引用 -> 栈区


循环引用的解决方法


  1. weak-strong-dance
  2. _block修饰对象(需要注意的是在block内部需要置空对象,而且block必须调用)
  3. 传递 self作为block的参数
  4. NSProxy


__block ViewController *vc = self;  
self.cjlBlock = ^(void){  
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{  
        NSLog(@"%@",vc.name);  
        vc = nil;//手动释放  
    });  
};  
self.cjlBlock();


NSProxy


  1. 多继承


- (void)cjl_proxyTest{
    Dog *dog = [[Dog alloc] init];
    Cat *cat = [[Cat alloc] init];
    CJLProxy *proxy = [CJLProxy alloc];
    [proxy transformObjc:cat];
    [proxy performSelector:@selector(eat)];
    [proxy transformObjc:dog];
    [proxy performSelector:@selector(shut)];
}


  1. 循环引用


self.timer = [NSTimer timerWithTimeInterval:1 target:[CJLProxy proxyWithObjc:self] selector:@selector(print) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];


Block底层分析


block本质 -> 对象 -> 函数(匿名函数) -> 结构体


  1. block为什么需要调用 ->函数声明(_main_block_func_0)
    执行具体的函数实现 -> block的FuncPtr指针 -> block
  2. block如何获取外界变量 -> 在内部会自动生成同一个属性来保存
  3. __block原理 -> 外界变量会生成__Block_byref_a_0结构体 -> 保存原始变量的指针和值 -> 传给block


block三次copy分析


[NSMethodSignature signatureWithObjCTypes:"v8@?0"]

block -> 结构 -> block_layout (底层结构)


byref 结构


  • 第一层 -> 用过_Block_copy -> 对象自身的copy -> 从栈区拷贝至堆区
  • 第二层 -> 根据不同类型进行不同操作, -> __block -> 只有__block才有这个操作 -> _Block_byref_copy -> 对象 -> Block_byref结构体类型
  • 第三层 -> 对象类型(NSString)才有 -> _Block_object_assign -> 对__block修饰的当前变量拷贝


只有__block修饰的对象, block的copy才有三层.




目录
相关文章
|
5月前
|
C++
C/C++内存管理(2):`new`和`delete`的实现原理
C/C++内存管理(2):`new`和`delete`的实现原理
|
6月前
|
编译器 调度 C++
block的四种基本使用方式
block的四种基本使用方式
78 0
|
存储 人工智能 缓存
3.9.1Cache的基本概念和原理
计算机组成原理之Cache的基本概念和原理
154 0
3.9.1Cache的基本概念和原理
|
存储 编译器 Linux
【C++】内存管理 —— new和delete底层实现原理
【C++】内存管理 —— new和delete底层实现原理
501 0
【C++】内存管理 —— new和delete底层实现原理
|
编译器 C++
block原理
block本质上也是一个OC对象,它内部也有个isa指针;block是封装了函数调用以及函数调用环境的OC对象
217 0
block原理
关于block的本质,你懂了吗?
block应用的目的: 把将来想要执行的代码封装起来,然后在恰当的时刻再执行代码。 block本质: 1、block是封装了函数调用和函数调用环境(如:block内部要使用的参数)的OC对象。 2、block本质上也是一个OC对象,它内部也有一个isa指针(只要内部有一个isa指针,我们就可以认为他是OC对象,因为NSObject作为最基础的OC对象,第一个成员变量就是isa指针,这是OC对象的特征)。
270 0
关于block的本质,你懂了吗?
|
存储 SQL 缓存
面试题:你有没有搞混查询缓存和Buffer Pool?谈谈看!
面试题:你有没有搞混查询缓存和Buffer Pool?谈谈看!
244 0
|
存储 消息中间件 缓存
老面试官问我:LRU 和 Innodb Buffer Pool 有什么关系?
老面试官问我:LRU 和 Innodb Buffer Pool 有什么关系?
老面试官问我:LRU 和 Innodb Buffer Pool 有什么关系?
|
存储 缓存 算法
LRU——LinkedListMap的实现原理
LRU是Least Recently Used的缩写,即最近最少使用,当超过容量时,自动删除最近最少使用的项目。 LRU在android开发中最常见的就是图片加载框架中的缓存逻辑。在java中可以利用LinkedListMap很方便的实现LRU
284 0