iOS底层系列 - Block

288 阅读1分钟

一、block 的本质

Block是 将函数封装起来的对象 既然 block内部封装了函数。

block 内部会把需要执行的代码,转换为一个 function 函数,然后通过结构体 block_impl 进行持有,在执行的时候调用 block 的 function 函数。

二、block 的代码结构

三、Block 相关知识

1.block 的变量捕获机制

2. block 的类型

MRC 下有:

  • GlobalBlock(全局) 没有引用任何外部变量。
  • StackBlock(栈) 引用了外部变量。
  • MallocBlock(堆)对栈Block进行copy。

ARC 下:

  • Block自动COPY,不再有栈Block,只有堆 Block 和 全局 Block.

3. block 的 copy

4. 对象类型的auto变量

5. __block修饰符

6. 被__block修饰的对象类型

7. block 解决循环引用的几种方法

8. 有几种方式去调用 Block

void (^block)(void) = ^{
 NSLog(@"block get called");
 };


 //1. blcok()
 block();


 //2. 利用其它方法去执行 block
 [UIView animateWithDuration:0 animations:block];


 //3.
 [[NSBlockOperation blockOperationWithBlock:block] start];


 //4. NSInvocation
 NSMethodSignature *signature = [NSMethodSignature signatureWithObjCTypes:"v@?"];
 NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
 [invocation invokeWithTarget:block];


 //5.DLIntrospection invoke
 [block invoke];


 //6. 指针调用
 void *pBlock = (__bridge void *)block;
 void (*invoke)(void *, ...) = *((void **)pBlock + 2);
 invoke(pBlock);


 //7. 利用 Clang
 __strong void(^cleaner)(void) __attribute ((cleanup(blockCleanUp),unused)) = block;


 //8. 内联一个汇编 完成调用
 asm("callq *0x10(%rax)");


 static void blockCleanUp (__strong void (^*block)(void)) {
 (*block)();
 }