我想创建一个允许块更新其内容的属性。对于一个典型的变量(即不是自动合成的等),我会在声明前加上__block
.
有没有办法制作一个能够被块更新的属性?
编辑:一些答案说只是使用属性设置器方法。我真正想做的是将对象添加到可变数组中,所以我真的不想创建一个新的可变数组并将其设置回使用setProperty:
or.property =
每次的属性。是否可以在没有所有这些内存分配的情况下修改属性?
我想创建一个允许块更新其内容的属性。对于一个典型的变量(即不是自动合成的等),我会在声明前加上__block
.
有没有办法制作一个能够被块更新的属性?
编辑:一些答案说只是使用属性设置器方法。我真正想做的是将对象添加到可变数组中,所以我真的不想创建一个新的可变数组并将其设置回使用setProperty:
or.property =
每次的属性。是否可以在没有所有这些内存分配的情况下修改属性?
这不是正确的思考方式。您要修改具有属性的对象。因此,您捕获块中的对象,并调用其访问器 ( setFoo:
) 来修改属性。
编辑:从各种编辑中,您可能会混淆 ObjC 对象的工作方式和 C++ 的工作方式。ObjC 只使用指向对象的指针,很少复制它们,并且缺乏const
对象的概念(有不可变对象,但这只是因为它们没有修改器;你不能const
像 C++ 中那样使用可变对象)。
__block
只是意味着“这个变量(不是它指向的对象;这个实际变量)应该通过引用而不是通过值传递给块)。” 所以当我说:
__block id foo;
这意味着可以更改foo
指针本身。foo
它与指向的对象是否可以变异完全无关。这对全局或 ivar 没有意义。ivars 是隐式结构字段。当您说_ivar
在块内时,编译器会将其隐式转换为self->_ivar
然后捕获self
. 它不捕获_ivar
(因为这只是self
结构的偏移量)。最好使用访问器来做同样的事情,因为它更明确你在做什么,你可以使用__weak
这种方式。
__block
用于声明块可能想要更改的局部变量。
属性也不是局部变量,当您只想向可变数组添加一些内容时,也不需要更改变量。变量没有改变,改变的是变量背后的对象状态。
当你想修改一个块中的变量时,你使用 __block;在您的情况下,您想要做的不是修改变量(它仍然指向相同的NSMutableArray
),而只是向它发送一条消息(addObject:
)。你不需要 __block 。
无需在@property
声明中添加任何内容。因为它们可以被块访问和修改而没有任何麻烦。根据文档:
在块对象的代码主体中,可以用五种不同的方式处理变量。
您可以引用三种标准类型的变量,就像引用函数一样:
- 全局变量,包括静态局部变量
- 全局函数(在技术上不是变量)
- 封闭范围内的局部变量和参数
块还支持另外两种类型的变量:
- 在功能级别是
__block
变量。这些在块(和封闭范围)内是可变的,并且如果任何引用块被复制到堆中,它们就会被保留。const
进口。以下规则适用于块内使用的变量:
- 全局变量是可访问的,包括存在于封闭词法范围内的静态变量。
- 传递给块的参数是可访问的(就像函数的参数一样)。
- 封闭词法范围的本地堆栈(非静态)变量被捕获为
const
变量。
它们的值取自程序中块表达式的位置。在嵌套块中,值是从最近的封闭范围捕获的。- 使用存储修饰符声明的封闭词法范围的局部变量
__block
由引用提供,因此是可变的。
任何更改都反映在封闭词法范围中,包括在同一封闭词法范围内定义的任何其他块。- 在块的词法范围内声明的局部变量,其行为与函数中的局部变量完全相同。
块的每次调用都会提供该变量的新副本。这些变量又可以用作包含在块中的块中的常量或引用变量。