Block 的原理

1.Block的本质是一个结构体指针, 回调原理: 通过当前的block对应的结构体指针找到对应的结构体,然后在结构体中找到对应的函数名称, 最后调用函数 .
2.通过__block \ static \ 全局变量 修饰或定义的变量,传入到 block 对应的结构体中实质时传入了对应的变量地址& a, 所以修改变量后block 内部的变量也随着响应的改变. 
3.局部静态变量则传入的是实际的值, 所以即便修改原来的变量 block 内部的值仍不会变化.
EG:
ObjC 代码:
#import <Foundation/Foundation.h>

// 局部变量
void test1(){
   
int a = 10 ;
   
void (^block)() = ^{
        NSLog(
@"test1 a = %d" , a);
    };
    a =
20 ;
    block();
}
// 局部静态变量
void test2(){
 
static   int a = 10 ;
   
void (^block)() = ^{
        NSLog(
@"test2 a = %d" , a);
    };
    a =
20 ;
    block();
}
//__block 修饰
void test3(){
   
__block   int a = 10 ;
   
void (^block)() = ^{
        NSLog(
@"test3 a = %d" , a);
    };
    a =
20 ;
    block();
}
// 全局变量调用
int a = 30 ;
void test4(){
   
        a =
50 ;
       
void (^block)() = ^{
            NSLog(
@"test4 a = %d" , a);
        };
        a =
20 ;
        block();
}

int main( int argc, const char * argv[]) {
   
@autoreleasepool {
        test1();
//10
        test2();
//20
        test3();
//20
        test4();
//20

    }
   
return 0 ;
}
编译过后的c++代码;
struct __test1_block_impl_0 {
  struct __block_impl impl;
 
struct __test1_block_desc_0* Desc;
 
int a;
  __test1_block_impl_0(
void *fp, struct __test1_block_desc_0 *desc, int _a, int flags= 0 ) : a(_a) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};
static void __test1_block_func_0( struct __test1_block_impl_0 *__cself) {
 
int a = __cself->a; // bound by copy

        NSLog((NSString *)&__NSConstantStringImpl__var_folders_0n_2blpmxd960zf5lxdfdrd9l9r0000gn_T_main_504a7b_mi_0, a);
    }

static struct __test1_block_desc_0 {
  size_t reserved;
  size_t Block_size;
} __test1_block_desc_0_DATA = {
0 , sizeof ( struct __test1_block_impl_0)};
void test1(){
   
int a = 10 ;
   
void (*block)() = (( void (*)())&__test1_block_impl_0(( void *)__test1_block_func_0, &__test1_block_desc_0_DATA, a));
    a =
20 ;
    ((
void (*)(__block_impl *))((__block_impl *)block)->FuncPtr)((__block_impl *)block);
}


struct __test2_block_impl_0 {
 
struct __block_impl impl;
 
struct __test2_block_desc_0* Desc;
 
int *a;
  __test2_block_impl_0(
void *fp, struct __test2_block_desc_0 *desc, int *_a, int flags= 0 ) : a(_a) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};
static void __test2_block_func_0( struct __test2_block_impl_0 *__cself) {
 
int *a = __cself->a; // bound by copy

        NSLog((NSString *)&__NSConstantStringImpl__var_folders_0n_2blpmxd960zf5lxdfdrd9l9r0000gn_T_main_504a7b_mi_1, (*a));
    }

static struct __test2_block_desc_0 {
  size_t reserved;
  size_t Block_size;
} __test2_block_desc_0_DATA = {
0 , sizeof ( struct __test2_block_impl_0)};
void test2(){
 
static int a = 10 ;
   
void (*block)() = (( void (*)())&__test2_block_impl_0(( void *)__test2_block_func_0, &__test2_block_desc_0_DATA, &a));
    a =
20 ;
    ((
void (*)(__block_impl *))((__block_impl *)block)->FuncPtr)((__block_impl *)block);
}

struct __Block_byref_a_0 {
 
void *__isa;
__Block_byref_a_0 *__forwarding;
 
int __flags;
 
int __size;
 
int a;
};

struct __test3_block_impl_0 {
 
struct __block_impl impl;
 
struct __test3_block_desc_0* Desc;
  __Block_byref_a_0 *a;
// by ref
  __test3_block_impl_0(
void *fp, struct __test3_block_desc_0 *desc, __Block_byref_a_0 *_a, int flags= 0 ) : a(_a->__forwarding) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};
static void __test3_block_func_0( struct __test3_block_impl_0 *__cself) {
  __Block_byref_a_0 *a = __cself->a;
// bound by ref

        NSLog((NSString *)&__NSConstantStringImpl__var_folders_0n_2blpmxd960zf5lxdfdrd9l9r0000gn_T_main_504a7b_mi_2, (a->__forwarding->a));
    }
static void __test3_block_copy_0( struct __test3_block_impl_0*dst, struct __test3_block_impl_0*src) {_Block_object_assign(( void *)&dst->a, ( void *)src->a, 8 /*BLOCK_FIELD_IS_BYREF*/ );}

static void __test3_block_dispose_0( struct __test3_block_impl_0*src) {_Block_object_dispose(( void *)src->a, 8 /*BLOCK_FIELD_IS_BYREF*/ );}

static struct __test3_block_desc_0 {
  size_t reserved;
  size_t Block_size;
 
void (*copy)( struct __test3_block_impl_0*, struct __test3_block_impl_0*);
 
void (*dispose)( struct __test3_block_impl_0*);
} __test3_block_desc_0_DATA = {
0 , sizeof ( struct __test3_block_impl_0), __test3_block_copy_0, __test3_block_dispose_0};
void test3(){
    __attribute__((__blocks__(byref))) __Block_byref_a_0 a = {(void*)0,(__Block_byref_a_0 *) &a , 0, sizeof(__Block_byref_a_0), 10};
    void (*block)() = ((void (*)())&__test3_block_impl_0((void *)__test3_block_func_0, &__test3_block_desc_0_DATA, (__Block_byref_a_0 *) &a , 570425344));
    (a.__forwarding->a) = 20 ;
    ((
void (*)(__block_impl *))((__block_impl *)block)->FuncPtr)((__block_impl *)block);
}

int a = 30 ;

struct __test4_block_impl_0 {
 
struct __block_impl impl;
 
struct __test4_block_desc_0* Desc;
  __test4_block_impl_0(
void *fp, struct __test4_block_desc_0 *desc, int flags= 0 ) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};
static void __test4_block_func_0( struct __test4_block_impl_0 *__cself) {

            NSLog((NSString *)&__NSConstantStringImpl__var_folders_0n_2blpmxd960zf5lxdfdrd9l9r0000gn_T_main_504a7b_mi_3, a);
        }

static struct __test4_block_desc_0 {
  size_t reserved;
  size_t Block_size;
} __test4_block_desc_0_DATA = {
0 , sizeof ( struct __test4_block_impl_0)};
void test4(){

        a =
50 ;
       
void (*block)() = (( void (*)())&__test4_block_impl_0(( void *)__test4_block_func_0, &__test4_block_desc_0_DATA));
        a =
20 ;
        ((
void (*)(__block_impl *))((__block_impl *)block)->FuncPtr)((__block_impl *)block);
}

int main( int argc, const char * argv[]) {
   
/* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool;
        test1();
        test2();
        test3();
        test4();

    }
   
return 0 ;
}



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值