美文网首页iOS-block知识
iOS-Block03-对auto、static 全局变量的引用

iOS-Block03-对auto、static 全局变量的引用

作者: IBigLiang | 来源:发表于2019-08-27 10:20 被阅读0次

这里,我们简单的讨论一下,当block在引用auto、static和全局变量时,block内部对这些变量是如何引用的。首先,我们先来看下main.m函数里面的内容:

#import <Foundation/Foundation.h>

int c = 10;
static int d = 20;

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        auto int a = 1;
        static int b = 2;
       
       void (^block)(void) = ^{
            NSLog(@"这是一个block");
           NSLog(@"a is %d --- b is %d -- c is %d -- d is %d", a, b, c, d);
        };
        
        block();
    }
    return 0;
}

main函数中关于block部分的代码在main.cpp中被编译成为以下代码:

        auto int a = 1;
        static int b = 2;
       void (*block)(void) = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, a, &b));

        ((void (*)(__block_impl *))((__block_impl *)block)->FuncPtr)((__block_impl *)block);

如果看了之前笔者有关于block的文章的话,这里面我们已经很熟悉了,很大一部分代码是强制转换 我们可以大致简写为:

         auto int a = 1;
         static int b = 2;
         block = (&__main_block_impl_0(__main_block_func_0, &__main_block_desc_0_DATA, a, &b));
         block->FuncPtr(block);

然后我们看看__main_block_impl_0这个结构体:

  struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  int a;
  int *b;
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int _a, int *_b, int flags=0) : a(_a), b(_b) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};

在上面这个结构体中,我们可以发现,block根本没有定义跟c、d相关的变量,单单是对a、b进行了处理。但是我们知道在block中,我们是打印了a、b、c、d变量了,不信的话,我们可以看下block块内的部分的cpp代码:

static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
  int a = __cself->a; // bound by copy
  int *b = __cself->b; // bound by copy

            NSLog((NSString *)&__NSConstantStringImpl__var_folders_tv_bzqp7v7d453fs34hx6hm6k9m0000gp_T_main_6be123_mi_0);
           NSLog((NSString *)&__NSConstantStringImpl__var_folders_tv_bzqp7v7d453fs34hx6hm6k9m0000gp_T_main_6be123_mi_1, a, (*b), c, d);
}

所以,唯一的解释,就是block是不会对全局变量(不管有没有static修饰)都是不会在block内部做处理的,可以直接得到全局变量的值。
然后我们再来看看a和b
a我们知道是: auto int a = 1; 然后在block结构体内部是定义了一个 int a;
而b我们知道是static int b = 2; 然后block结构体中是定义了一个 int *b;
从上我们可以得到的结论就是,对于像a这种auto变量的话,本身它就是在栈上的,离开了作用域之后,就自动销毁了,只存在于局部,所以block在捕获它的时候,本身就是值传递;
但是,对于像函数内定义的b这样的static变量,它本身是一个静态变量,不会因为作用域的问题而自动销毁,所以block在捕获它的时候需要的是指针传递,而不是值传递。
所以综上可得的结果:
1 、block对全局变量(不管有没有static修饰)引用时,都是不会在block内部做处理的,因为本身block就可以直接得到全局变量的值。
2、对于auto变量,本身它就是在栈上的,离开了作用域之后,就自动销毁了,只存在于局部,所以block在捕获它的时候,本身就是值传递。
3、对于函数内定义的static变量,它本身是一个静态变量,不会因为作用域的问题而自动销毁,所以block在捕获它的时候需要的是指针传递,而不是值传递。
希望对大家有所帮助!!!

相关文章

  • iOS-Block03-对auto、static 全局变量的引用

    这里,我们简单的讨论一下,当block在引用auto、static和全局变量时,block内部对这些变量是如何引用...

  • 关于static关键字的个人总结

    1,static全局变量和普通全局变量的区别:static全局变量只初始化一次,防止在其他文件单元引用 2,sta...

  • iOS - C 中的存储类

    文章引用 一、C 中的四种存储类: auto register static extern 二、 auto aut...

  • auto / static / extern

    auto 当修饰局部变量的时候加上auto(默认),多次调用函数值没有累加 不可以修饰全局变量 static 当修...

  • staic和bridge

    1.static全局变量与普通的全局变量有什么区别?:static全局变量只初使化一次,防止在其他源文件中被引用;...

  • static全局变量与普通的全局变量有什么区别

    static全局变量与普通的全局变量有什么区别:static全局变量只初使化一次,防止在其他文件单元中被引用; s...

  • iOS开发一些小总结(一)

    static关键字区别 static全局变量只初始化一次,防止在其他文件单元中被引用 static函数在内存中只有...

  • C

    变量 存储类 auto 局部变量的默认存储类,只能用来修饰局部变量 static 全局变量的默认存储类,作用...

  • 在php函数中对global和static变量进行引用赋值操作导

    对global和static关键字的简单介绍 global关键字是用于在函数中创建一个对全局变量的引用,在函数内部...

  • static、extern、const

    static 修改全局变量 1.static 修饰的全局变量只能在本文件中访问,别的文件中访问不到,对声明他的文件...

网友评论

    本文标题:iOS-Block03-对auto、static 全局变量的引用

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