变量的地址在块内时会发生变化

时间:2016-01-24 17:21:12

标签: objective-c objective-c-blocks

在以下代码中,b的地址在块内时会发生变化。为什么?如果它为b更改,为什么不为?

int b =42;
    int  *a = &b;

    printf("%p", a);
    printf("%p", &b);



    void (^testBlock)(void) = ^(void)
    {
        printf("%p", a);  //address not changed
        printf("%p", &b); //address is changed

    };
    testBlock();

    printf("%p", a); //address not changed
    printf("%p", &b);//address not changed

3 个答案:

答案 0 :(得分:1)

块类似于函数。考虑:

void testFunc(int *a, int b)
{
    printf("%p", a);
    printf("%p", &b);
}

int b =42;
int  *a = &b;

printf("%p", a);
printf("%p", &b);

testFunc(a, b);

printf("%p", a); //address not changed
printf("%p", &b);//address not changed

对函数的调用已将ab的值复制到testFunc()中的局部变量(参数),这些变量恰好也被命名为a和{ {1}}。这些变量与另一个范围中的ba不同。它们具有相同的价值。因此,参数的地址不同于其他变量的地址。

如果是b,您需要打印其值,而不是其地址。所以,这是相同的,因为价值是被复制的。在a的情况下,您正在打印其地址。

答案 1 :(得分:0)

Blocks维护从周围范围捕获的非__block局部变量的单独副本,因为块可能比它们创建的范围更长。您可以将此单独副本视为一种“实例变量”块在执行时透明地使用的块对象。这个单独的副本在创建块时初始化为外部变量的值。

由于它是一个单独的副本,因此它将具有与原始变量不同的地址(这就是&b不同的原因)。但是,该变量的两个副本的最初都是相同的(直到有人更改外部副本),因为块的副本是使用外部副本的值初始化的(这就是为什么{{1两者都是一样的。

答案 2 :(得分:-1)

int bint *a完全不同,因为b是一个值,而a是一个参考。

Blocks捕获它们需要执行的变量,以避免在变量释放后访问它。这对于值类型的意义可能是它被复制(与将值传递给函数时复制的方式相同),这就是为什么你会看到b的不同地址。