一、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)();
}