Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
objective-c块中捕获变量的概念存在问题_Objective C_Objective C Blocks - Fatal编程技术网

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这不一定与块有关,而是与指针的工作方式有关。保存内存地址(又称指针)的变量可以保持不变,但该内存地址的内容会发生变化。这并不意味着变量本身会改变,因为变量只是指向内存位置的指针,而不是对象本身。