美文网首页将来跳槽用2019IV
__block修饰基本数据类型

__block修饰基本数据类型

作者: 大兵布莱恩特 | 来源:发表于2019-02-22 14:58 被阅读3次

block内部为什么不能够直接修改 auto 变量的值?

image.png

因为 auto age 变量是在栈上存放的, 当函数作用域结束时就会被销毁,而 block 执行的函数是在另一个函数方法里, 这个函数是无法访问到 auto age 变量的 ,虽然 block内部也会生成一个一模一样的变量 age 但是这个 age变量 是 block 内部的 不会影响到外部的 auto 变量 age . 因此 block 内部是无法去修改

怎么样才能在 block 内部去修改局部变量的值呢 ?

有两种方法可以修改到 变量 age 的值 ,第一种 用static 修饰 age 变量 ,由于是静态变量 它会存放在一个 .data区 这块的内存是随着应用的生命周期而结束,这样就造成了 age 这个变量 无法被释放掉
第二种方法 就是用 __block 去修饰 age 变量,即不改变 age 是 auto 类型的变量 又可以在 block 内部去修改 age 的值 .

image.png

__block是怎么实现对局部变量的修改呢?

带着这个问题 我们将这段代码转成C++的代码 一窥究竟


void testBlock() {

去掉一些强制类型转换后 简化为下边的代码
 MyBlock block;
__Block_byref_age_0 age = {0,&age, 0, sizeof(__Block_byref_age_0), 10};
 block = &__testBlock_block_impl_0(__testBlock_block_func_0, &__testBlock_block_desc_0_DATA,&age, 570425344));
 block->FuncPtr)(block);
}

///Block 内部结构 不再是 int age 而是 __Block_byref_age_0 *age

struct __testBlock_block_impl_0 {
  struct __block_impl impl;
  struct __testBlock_block_desc_0* Desc;
  __Block_byref_age_0 *age; // by ref
  __testBlock_block_impl_0(void *fp, struct __testBlock_block_desc_0 *desc, __Block_byref_age_0 *_age, int flags=0) : age(_age->__forwarding) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};

__Block_byref_age_0 其实也是一个OC对象 内部有 isa 指针

struct __Block_byref_age_0 {
  void *__isa; ///表示它是一个OC对象
__Block_byref_age_0 *__forwarding; ///一个指向自身的结构体指针
 int __flags;
 int __size; ///内存大小
 int age; ///外部 auto 变量age的值
};

__Block_byref_age_0 age = {0,&age, 0, sizeof(__Block_byref_age_0), 10};

同过 block 内部的 age -> __forwarding指针 -> age 去修改 age 的值


static void __testBlock_block_func_0(struct __testBlock_block_impl_0 *__cself) {
  __Block_byref_age_0 *age = __cself->age; // bound by ref
 ///同过 block 内部的 age -> __forwarding指针 -> age 去修改 age 的值
  (age->__forwarding->age) = 20;
  NSLog((NSString *)&__NSConstantStringImpl__var_folders_hj_pwgsq9614nb0vq4zd315tcx80000gn_T_main_163d3b_mi_0,(age->__forwarding->age));
 }

好了,我是大兵布莱恩特,欢迎加入博主技术交流群,iOS 开发交流群

QQ20180712-0.png

相关文章

  • Block(二)__block

    一、__block修饰基本数据类型的局部变量 1、被__block修饰的局部变量可以在Block内部修改,__bl...

  • 基础题

    block和weak的区别 block可以修饰对象和基本数据类型 weak只能修饰对象,也只能在ARC下使用 bl...

  • block与__block

    block内局部变量的修改 1.基本数据类型: 1)不使用__block修饰 代码: 运行结果: 结论:对于基本数...

  • __block修饰符(四)

    一、不加__block修饰符的情况下在block内部修改变量 1、基本数据类型的auto局部变量 在block中无...

  • __block到底是啥?(四)

    __block修饰基本数据类型 前面我们说到,block内部改变自动变量的方法: 将自动变量转为指针传入 用__b...

  • iOS Block Part5:block捕获__block对象

    __block修饰对象类型 编译结果: 结构示意图: __block修饰的对象数据类型的变量也能实现block内外...

  • iOS关键字用法 - nullability annotatio

    以下关键字只能修饰strong/copy/block指针类型的对象,不能修饰assign基本数据类型使用关键字好处...

  • __block和__weak修饰符的区别

    1、__block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。 2、__weak...

  • __block修饰基本数据类型

    block内部为什么不能够直接修改 auto 变量的值? 因为 auto age 变量是在栈上存放的, 当函数作...

  • __block和__weak的区别

    1.__block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。 2.__weak...

网友评论

    本文标题:__block修饰基本数据类型

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