objective-c块中捕获变量的概念存在问题
我已经读取了objective-c块中捕获变量的概念存在问题,objective-c,objective-c-blocks,Objective C,Objective C Blocks,我已经读取了str变量,这里的变量在块内是只读的。 但是当我在上面调用appendString方法时,变量str被修改了!怎么做 NSMutableString *str = [NSMutableString stringWithFormat:@"Hi, My name is "]; int k=2; void (^testBlock)(void) = ^(void) { k = k*2; //Error as expected [str appendString:@"M
str
变量,这里的变量在块内是只读的。
但是当我在上面调用appendString
方法时,变量str
被修改了!怎么做
NSMutableString *str = [NSMutableString stringWithFormat:@"Hi, My name is "];
int k=2;
void (^testBlock)(void) = ^(void)
{
k = k*2; //Error as expected
[str appendString:@"Mickey Mouse"]; //no Error!!
}
testBlock();
可以说,块不允许更改指针(地址),但允许修改对象值(而不是存储对象指针的变量值) 例如,可以更改可变对象,如可变字符串(追加字符串)和可变数组(插入/更新/删除)。但如果没有
\uu块
修饰符,则无法将指针重新分配到块内的不可变数组
这里的可变对象的行为类似于块中的属性/IVAR。变量
str
没有被修改,它仍然具有相同的值-即,它指向相同的内存地址。请尝试NSLog(@“%p”,str)
亲自查看
调用appendString:
会改变str
指针所指地址中存储的内容。指针值不变,这就是为什么您可以操纵str
的值
作为练习,尝试添加一个类Person
,并使用它的实例而不是字符串。您可以去更改该对象的各种属性,但仍然可以在同一实例上操作
int a = 10;
/*within the block */
a = a/5;
//prohibited without a __block storage specifier
现在看这个,
int a =10;
int *b= &a;
/*within the block */
*b = (*b)/5;
//No Error. The value at the address was only changed but the pointer b is still pointing to the same address viz &a
这是一种非常糟糕的描述方式。指针是一个值。你的区别令人困惑。如果你真的认为指针不是一个值,你需要回去阅读一些C语言的基本文本。(要说迂腐,存储在变量名引用的内存地址中的内存地址就是值,但在本例中迂腐并不能真正提供清晰性。)引用C11标准草案:指针类型描述了一个对象,其值提供了对引用类型实体的引用。它与讨论的问题有关。你的想法表明你和海报一样困惑,即使你的困惑是在不同的点上。不能修改块中的函数范围变量,因为它们存储在堆栈上,并且堆栈帧可能在执行块之前消失。使用
\u块
修饰符时,编译器会注意确保该变量可供块修改,但不会改变作用域语义。continued块捕获变量的值,这意味着如果该值是指针,则对象将被保留。对象不被块捕获,也不在堆栈上。它就像任何其他对象一样,可以使用任何可用的引用发送消息。明白了!我想知道你是从哪里读到这篇文章的,因为我已经阅读了整个程序块的编程指南,但我还是没能理解它@Viki这不一定与块有关,而是与指针的工作方式有关。保存内存地址(又称指针)的变量可以保持不变,但该内存地址的内容会发生变化。这并不意味着变量本身会改变,因为变量只是指向内存位置的指针,而不是对象本身。