Block

115

1. Block是将函数及其执行上下文封装起来的对象

Block在编译后的函数体是一个c函数,在调用时直接通过指针调用。

struct Block_layout {
    void *isa;
    int32_t flags;  //引用计数
    int32_t reserved;
    void *invoke;   //函数指针
    struct Block_descriptor1 *descriptor;
};

struct Blcok_descriptor1{
    uintptr_t reserved;
    uintptr_t size;
}
2. 截获变量
{
    int multi = 6;
    void (^Block)(int) = ^int(int num) {
        return num *multi;
    }
    multi = 4;

    NSLog(@"result is %d", Block(2));
}
  • 局部变量
    1. 基本数据类型: 截获其值
    2. 对象类型:连同所有权修饰符一起截获
  • 静态局部变量:以指针形式截获
  • 全局变量:不截获
  • 静态全局变量:不截获
3. __block修饰符

一般情况下,对被截获变量进行赋值操作需要使用__block修饰符

NSMutableArray *arr = [NSMutableArray array];
void(^block)(void) = ^{
    [arr addobject:@1];
};

__block NSMutableArray *arr = [NSMutableArray array];
void(^block)(void) = ^{
    arr = [NSMutableArray array];
}

静态局部变量、全局变量、静态全局变量不涉及截获操作,不需要__block修饰符

__block修饰的变量变成了对象

struct _Block_byref_multiplier_0 {
    void *__isa;
    __Block_byref_multipiler_0 *__forwarding;
    int __flags;
    int __size;
    int multipiler;
}

栈上的__forwarding指向自身

4. Block内存管理

5. Block循环引用