Block 底层1

Block

本质来讲是OC 对象,其内部有一个isa指针。

1 Block 的声明

一言以蔽之: returnType ( ^blockName)(parameterTypes) = ^returnType (parameters) {};

  • returnType 返回的类型 可以为Void,为Void的时候可以省略
  • ^blockName Block的名字
  • parameterTypes 参数类型
  • parameters 变量的名字
// 1 有返回值 有参数
int(^Sum)(int,int) = ^int (int a, int b){
    return a + b;
};

NSLog(@"%d",Sum(5,5));


// 2 无返回值有参数 
void (^SayHi)(NSString *) = ^(NSString *hello){
    NSLog(@"hello-%@",hello);
};

SayHi(@"China");

// 3 无返回值无参数
void (^Run)(void) = ^{
    NSLog(@"Nothing happend");
};

Run();





我在代码中常用的定义的方式

  • @property (copy,nonatomic)void(^openBtnClickBlock)(BOOL);

  • typedef void(^SKBlock)(NSString *);

2 本质是什么?

本质是OC 对象

cd 到文件夹 执行命令行,生成main.cpp

xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m

找到main 删除 copy 出来 咱们的OC 代码转为C++ 之后的代码

void (*Run)(void) = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA));

//  __main_block_impl_0 的定义如下
// 其中的__block_impl 存放的是一些变量信息,其中存在isa指针,本质上还是一个OC的对象
// 然后就是初始化构造函数
// __main_block_desc_0 这是block 的描述信息
struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
    // 构造函数 返回的是结构体对象
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int flags=0) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};

// __block_impl 定义如下
struct __block_impl {
void *isa;
int Flags;
int Reserved;
void *FuncPtr;
};

// __main_block_func 如下
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
            NSLog((NSString *)&__NSConstantStringImpl__var_folders_fy_885kj4n56w7g9r9_jkpsn25h0000gp_T_main_2c916c_mi_0);
        }

// __main_block_desc_0_DATA 定义
static struct __main_block_desc_0 {
  size_t reserved;
  size_t Block_size;
} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0)};



3 Block 的类型

通过class 方法 或者isa 指针可以查看具体类型。

  • 1 NSGlobalBlock 没有访问auto 变量 内存分配在数据区域
  • 2 NSStackBlock 访问了auto 变量 内存分配在栈区域
  • 3 NSMallocBlock NSStackBlock 调用了copy 方法,没存分配在堆区域

每一种的类型的block 复制之后的结果

        int meters = 1000;
        
        // 3 无返回值无参数
        void (^Run1)(void) = ^{
            NSLog(@"i have run %d meters",meters);
        } ;

        Run1();
        void (^Run2)(void) = ^{
            NSLog(@"i have run");
        } ;
        Run2();
        void (^Run3)(void) = [^{
            NSLog(@"i have run %d meters",meters);
        } copy];
        Run3();
// 之所以 没有stack Block 是因为 ARC 环境导致的 自动进行copy  stackBlock 的操作
        // 打印结果 __NSMallocBlock__--__NSGlobalBlock__--__NSMallocBlock__
        NSLog(@"%@--%@--%@",[Run1 class],[Run2 class],[Run3 class]);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值