在块内时变量的地址正在更改
Address of a variable is changing when inside a block
在下面的代码中,b
的地址在块内时发生变化。为什么?如果 b
发生变化,为什么 a 不发生变化?
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
int b
和int *a
是完全不同的,因为b
是一个值而a
是一个引用。
块捕获它们需要执行的变量,以避免在释放后访问变量。这对值类型意味着它可能被复制(与将值传递给函数时它被复制的方式相同),这就是为什么您看到 b
.
的不同地址的原因
一个块类似于一个函数。考虑:
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
对函数的调用已将 a
和 b
的值复制到 testFunc()
中的局部变量(参数)中,这些变量恰好也被命名为 a
和 b
。这些变量与其他范围内的 a
和 b
不同。它们只是具有相同的值。因此,参数的地址与其他变量的地址不同。
在 a
的情况下,您打印的是它的值,而不是它的地址。所以,这是一样的,因为价值是被复制的。对于 b
,您正在打印它的地址。
块维护从周围范围捕获的非__block
局部变量的单独副本,因为块可能比创建它们的范围长。您可以将这个单独的副本视为一种"instance variable" 块在执行时透明使用的块对象。这个单独的副本在创建块时被初始化为外部变量的值。
因为它是一个单独的副本,它的地址将与原始变量不同(这就是 &b
不同的原因)。但是,该变量的两个副本的 value 最初是相同的(直到有人更改外部副本),因为块的副本是用外部副本的值初始化的(这就是为什么a
两者相同)。
在下面的代码中,b
的地址在块内时发生变化。为什么?如果 b
发生变化,为什么 a 不发生变化?
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
int b
和int *a
是完全不同的,因为b
是一个值而a
是一个引用。
块捕获它们需要执行的变量,以避免在释放后访问变量。这对值类型意味着它可能被复制(与将值传递给函数时它被复制的方式相同),这就是为什么您看到 b
.
一个块类似于一个函数。考虑:
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
对函数的调用已将 a
和 b
的值复制到 testFunc()
中的局部变量(参数)中,这些变量恰好也被命名为 a
和 b
。这些变量与其他范围内的 a
和 b
不同。它们只是具有相同的值。因此,参数的地址与其他变量的地址不同。
在 a
的情况下,您打印的是它的值,而不是它的地址。所以,这是一样的,因为价值是被复制的。对于 b
,您正在打印它的地址。
块维护从周围范围捕获的非__block
局部变量的单独副本,因为块可能比创建它们的范围长。您可以将这个单独的副本视为一种"instance variable" 块在执行时透明使用的块对象。这个单独的副本在创建块时被初始化为外部变量的值。
因为它是一个单独的副本,它的地址将与原始变量不同(这就是 &b
不同的原因)。但是,该变量的两个副本的 value 最初是相同的(直到有人更改外部副本),因为块的副本是用外部副本的值初始化的(这就是为什么a
两者相同)。