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