美文网首页
2022-04-13 block笔记

2022-04-13 block笔记

作者: 我是小胡胡123 | 来源:发表于2022-04-13 08:59 被阅读0次
  • 什么是block
  • 什么是block调用
  • block截获变量
  • __block修饰符用在什么场景,__block变量__forwarding指针的作用
  • block的copy操作
  • block的循环引用

1、Objc测试代码

@implementation Ablock

int a3 = 3;
static int a4 = 4;

- (void)test {
    int a1 = 1;
    static int a2 = 2;
    __block int a5 = 5;
    __strong NSString *a6 = @"66";
    __unsafe_unretained NSString *a7 = @"77";
    int  (^someblock)(int b) = ^(int b){
        a1;
        a2;
        a3;
        a4;
        a6;
        a7;
        a5 = 55;
        return b+a1+a2+a3+a4+a5;
    };
    someblock(3);
}

@end

2、转化后的c++代码分析

使用clang可以转objc为c++代码
clang -rewrite-objc -fobjc-arc Ablock.m
当前目录下生成Ablock.cpp文件

原来的OC代码被编译转化成如下调用:



static void _I_Ablock_test(Ablock * self, SEL _cmd) {
    int a1 = 1;
    static int a2 = 2;
    __attribute__((__blocks__(byref))) __Block_byref_a5_0 a5 = {(void*)0,(__Block_byref_a5_0 *)&a5, 0, sizeof(__Block_byref_a5_0), 5};
    __attribute__((objc_ownership(strong))) NSString *a6 = (NSString *)&__NSConstantStringImpl__var_folders_4j_z1n6phgx4d11klg60p7d3b240000gn_T_Ablock_da6be4_mi_0;
    __attribute__((objc_ownership(none))) NSString *a7 = (NSString *)&__NSConstantStringImpl__var_folders_4j_z1n6phgx4d11klg60p7d3b240000gn_T_Ablock_da6be4_mi_1;


  // 什么是block
    //block封装函数和上下文的对象
    int (*someblock)(int b) = ((int (*)(int))&__Ablock__test_block_impl_0((void *)__Ablock__test_block_func_0, &__Ablock__test_block_desc_0_DATA, a1, &a2, a6, a7, 
        (__Block_byref_a5_0 *)&a5, 570425344));



  // block调用
   //调用block就是调用函数
    //    struct __Ablock__test_block_impl_0 类型强制转化为struct __block_impl  类型
    ((int (*)(__block_impl *, int))((__block_impl *)someblock)->FuncPtr)((__block_impl *)someblock, 3);
}

找到各类型定义如下:



struct __Block_byref_a5_0 { //__block转化为了结构体
  void *__isa; //有isa ,__block变量也转化为了对象
__Block_byref_a5_0 *__forwarding; //  __forwarding指针
 int __flags;
 int __size;
 int a5;  // block变量
};



struct __block_impl {
  void *isa; //是对象。
  int Flags; 
  int Reserved;
  void *FuncPtr;//函数指针
};



 void *_NSConcreteGlobalBlock[32];  //全局block
 void *_NSConcreteStackBlock[32]; //栈block
_NSConcreteMallocBlock //堆block



struct __Ablock__test_block_impl_0 { //block对象
  struct __block_impl impl;  //block对象。struct __Ablock__test_block_impl_0  和  struct __block_impl可以强制地址类型转换,因为它是内存第一个空间位置,所以互相转也没啥都是指向同一个内存首地址
  struct __Ablock__test_block_desc_0* Desc;
  int a1;
  int *a2;
  NSString *__strong a6;
  NSString *__unsafe_unretained a7;

  __Block_byref_a5_0 *a5; // by ref


  __Ablock__test_block_impl_0(void *fp, struct __Ablock__test_block_desc_0 *desc, int _a1, int *_a2, NSString *__strong _a6, NSString *__unsafe_unretained _a7, __Block_byref_a5_0 *_a5, int flags=0) : a1(_a1), a2(_a2), a6(_a6), a7(_a7), a5(_a5->__forwarding) {
    impl.isa = &_NSConcreteStackBlock; //栈block
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};

 int a3 = 3; //全局变量 不截获
static int a4 = 4;//静态全局变量 不截获

 // 这就是FuncPtr
static int __Ablock__test_block_func_0(struct __Ablock__test_block_impl_0 *__cself, int b) {
  __Block_byref_a5_0 *a5 = __cself->a5; // bound by ref    __block转换为对象,内部有__forwarding指针指向block变量。如果是  struct __block_impl 是栈类型block,__forwarding指向__block变量自己,如果是堆上,则指向堆上__block变量
  int a1 = __cself->a1; // bound by copy     基本数据类型,截获其值
  int *a2 = __cself->a2; // bound by copy。  静态局部变量, 截获指针
  NSString *__strong a6 = __cself->a6; // bound by copy   对象类型, 连同所属权修饰符一起截获
  NSString *__unsafe_unretained a7 = __cself->a7; // bound by copy  对象类型, 连同所属权修饰符一起截获

        a1;
        (*a2);
        a3;
        a4;
        a6;
        a7;
        (a5->__forwarding->a5) = 55;
        return b+a1+(*a2)+a3+a4+(a5->__forwarding->a5);
    }






static void __Ablock__test_block_copy_0(struct __Ablock__test_block_impl_0*dst, struct __Ablock__test_block_impl_0*src) {_Block_object_assign((void*)&dst->a6, (void*)src->a6, 3/*BLOCK_FIELD_IS_OBJECT*/);_Block_object_assign((void*)&dst->a7, (void*)src->a7, 3/*BLOCK_FIELD_IS_OBJECT*/);_Block_object_assign((void*)&dst->a5, (void*)src->a5, 8/*BLOCK_FIELD_IS_BYREF*/);}

static void __Ablock__test_block_dispose_0(struct __Ablock__test_block_impl_0*src) {_Block_object_dispose((void*)src->a6, 3/*BLOCK_FIELD_IS_OBJECT*/);_Block_object_dispose((void*)src->a7, 3/*BLOCK_FIELD_IS_OBJECT*/);_Block_object_dispose((void*)src->a5, 8/*BLOCK_FIELD_IS_BYREF*/);}

static struct __Ablock__test_block_desc_0 {
  size_t reserved;
  size_t Block_size;
  void (*copy)(struct __Ablock__test_block_impl_0*, struct __Ablock__test_block_impl_0*);
  void (*dispose)(struct __Ablock__test_block_impl_0*);
} __Ablock__test_block_desc_0_DATA = { 0, sizeof(struct __Ablock__test_block_impl_0), __Ablock__test_block_copy_0, __Ablock__test_block_dispose_0};

相关文章

  • 2022-04-13 block笔记

    什么是block 什么是block调用 block截获变量 __block修饰符用在什么场景,__block变量_...

  • 2022-04-13

    2022-04-13

  • Block常见使用总结(传值/作为参数/作为返回值等)

    来做个block的笔记。 block定义 block类型 block传值 block作为参数的方法定义与调用 bl...

  • runtime 之给 button 添加 block 事件支持

    这只是简单的笔记UIButton+block.h UIButton+block.m 使用

  • Day7 读书笔记&心得体会

    一、读书笔记回顾昨天的收获:什么是block、proc? block和proc是两种不同的东西, block有形无...

  • Objective-C的Block

    声明:本文是读了 做的笔记,以及结合本人写的例子总结的Block知识。 目录 Block入门什么是Block如何定...

  • __block和非__block

    自己的笔记: NSString *text = @"test"; testBlock block = ^{ dis...

  • Block 笔记

    Block表达式语法:^ 返回值类型 (参数列表) {表达式}声明Block类型变量语法:返回值类型 (^变量名)...

  • block笔记

    1.我在一个类中声明了一个block属性:a类 定义如下: 这里用的是weak修饰的,表示我不会将block从本身...

  • block(笔记)

    oc 里面的block:block确实是个很好用的东西,简单的来说就是做完一个事情后要干些什么,用了block就么...

网友评论

      本文标题:2022-04-13 block笔记

      本文链接:https://www.haomeiwen.com/subject/cleosrtx.html