将来跳槽用2019IV

__block修饰基本数据类型

2019-02-22  本文已影响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
上一篇 下一篇

猜你喜欢

热点阅读