澄清Apple的阻止文档? [英] Clarification on Apple's Block Docs?
问题描述
我正在解决一些关于块/ARC的保留周期问题,并且我努力使自己细微差别.任何指导表示赞赏.
I am working through some retain-cycle issues with blocks/ARC, and I am trying to get my head around the nuances. Any guidance is appreciated.
Apple关于块和变量"的文档(http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/Blocks/Articles/bxVariables.html)说:
Apple's documentation on "Blocks and Variables" (http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/Blocks/Articles/bxVariables.html) says the following:
如果在方法的实现内使用块,则规则 用于对象实例变量的内存管理更加微妙:
If you use a block within the implementation of a method, the rules for memory management of object instance variables are more subtle:
如果通过引用访问实例变量,则self会保留;如果 您通过值访问实例变量,该变量将保留. 以下示例说明了两种不同的情况:
If you access an instance variable by reference, self is retained; If you access an instance variable by value, the variable is retained. The following examples illustrate the two different situations:
dispatch_async(queue, ^{
// instanceVariable is used by reference, self is retained
doSomethingWithObject(instanceVariable);
});
id localVariable = instanceVariable;
dispatch_async(queue, ^{
// localVariable is used by value, localVariable is retained (not self)
doSomethingWithObject(localVariable);
});
我觉得这种解释令人困惑.
I find this explanation confusing.
- 这种适当使用按值"/按引用"术语吗?假设这些变量具有相同的类型(id),似乎它们之间的区别在于它们的范围.
-
我在通过引用"示例中看不到如何引用自我吗?如果使用访问器方法(例如,下面的-),我会发现自己被保留了.
- Is this appropriate use of the "by value" / "by reference" terminology? Assuming that these variables are of the same type (id), it seems like the distinguishing characteristic between them is their scope.
I do not see how self is being referenced in the "by reference" example? If an accessor method were being used, (e.g. - below), I could see self being retained.
doSomethingWithObject(self.instanceVariable);
doSomethingWithObject(self.instanceVariable);
对于何时可能要以一种或另一种方式做事,您有任何指导吗?
Do you have any guidance on when one might want to do things one way or the other?
推荐答案
-
按值"/按引用"术语的这种适当用法吗? 至少类似于典型用法.将值复制到局部变量就像将值复制到堆栈上一样.使用ivar就像将指针传递到存储在其他位置的值.
Is this appropriate use of the "by value" / "by reference" terminology? It's at least analogous to the typical use. Copying a value to a local variable is like copying a value onto the stack; using an ivar is like passing a pointer to a value that's stored somewhere else.
在通过引用"示例中看不到self是如何被引用的? 暗示self
.某些人实际上是写self->foo
而不是foo
来访问ivar只是为了提醒自己foo
是ivar.我不建议这样做,但重点是foo
和self->foo
表示同一意思.如果访问块内的ivar,将保留self
,以确保在块期间保留该ivar.
I do not see how self is being referenced in the "by reference" example? When you use an instance variable inside a method, the reference to self
is implied. Some people actually write self->foo
instead of foo
to access an ivar just to remind themselves that foo
is an ivar. I don't recommend that, but the point is that foo
and self->foo
mean the same thing. If you access an ivar inside a block, self
will be retained in order to ensure that the ivar is preserved for the duration of the block.
您对何时可能要用一种方式或另一种方式做事有任何指导吗? /此处按值区分.正如AliSoftware解释的那样,在创建块时会保留局部变量,就像在调用函数时复制按值传递的参数一样.就像通过引用访问通过引用传递的参数一样,通过自身访问ivar,因此直到您实际使用它时,才确定它的值.
Do you have any guidance on when one might want to do things one way or the other? It's useful to think in terms of the pass by reference/pass by value distinction here. As AliSoftware explained local variables are preserved when the block is created, just as parameters passed by value are copied when a function is called. An ivar is accessed through self just as a parameter passed by reference is accessed through a pointer, so its value isn't determined until you actually use it.
这似乎会为大量的变量声明带来很多额外的代码? 块在一段时间以来一直是该语言的功能之一现在,我还没有注意到这是一个问题.通常,您希望得到相反的行为:局部声明的变量,您可以在一个(或多个)块内进行修改. __block
存储类型使之成为可能.
it seems like this is going to result in a lot of additional code for additional variable declarations? Blocks have been a feature of the language for a while now, and I haven't noticed that this is a problem. More often, you want the opposite behavior: a variable declared locally that you can modify within a block (or several blocks). The __block
storage type makes that possible.
似乎避免声明彼此内部的块可能更可维护,因为最终可能会导致杂乱无章地保留对象? 让一个或多个块在需要的时间内保留对象没有任何问题-该对象将在使用该对象的块终止时立即释放.这与通常的Objective-c手动内存管理理念非常吻合,在Objective-c手册中,每个对象仅担心平衡自己的保留空间.避免多层嵌套块的一个更好的理由是,这种代码可能比需要的要难理解.
it seems like it may be more maintainable to avoid declaring the blocks inside of each other as one could ultimately end up with a potpourri of unintentionally retained objects? There's nothing wrong with letting one or more blocks retain an object for as long as they need it -- the object will be released just as soon as the blocks that use it terminate. This fits perfectly with the usual Objective-c manual memory management philosophy, where every object worries only about balancing its own retains. A better reason to avoid several layers of nested blocks is that that sort of code may be more difficult to understand than it needs to be.
这篇关于澄清Apple的阻止文档?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!