Why is a __block variable is moved to the heap BEFORE the block is copied? [closed]

一曲冷凌霜 提交于 2019-11-30 19:05:26

Let me preface this by saying: Blocks are weird.

Now, when you start out, you've declared a variable x, and also prefixed it with __block. What the heck is __block anyhow? Well, for objects captured in the lexical scope of the block, variables are -retain'ed so as to guarantee they are around when the block is executed. But for primitive variables, blocks secure their values by forcing them to be passed by const value rather than by reference. By prepending __block, you've given the compiler free reign to move your variable "magically" from the stack to the heap when the block is copied. To be clear, __block variables are, in fact, stack allocated, but they are moved to the heap (malloc()'d) when the block is copied.

But what about the weird changes in the location of x? Well, back to __block again. Because you're not using a const reference to x like a normal variable, blocks use a (slightly annoying) trick: A block creates a pointer to any __block variable, and if that variable is mutated, it is dereferenced. Ta da! Your variable didn't move from the stack to the heap, the block merely dereferenced the pointer to it and moved it in memory!

So, really, you're confused about where and when your variables are moved around. Your example is logging the correct values.

Your expected output is based on your assumption that the block is not copied until step 3-4. However, nothing in the Blocks specifications guarantees that that would be the case.

Yes, the block will be copied at the latest when you explicitly call -copy on it. But why can't it be copied earlier? It is never wrong to copy a block earlier. Therefore, when exactly a block is copied is undefined, and you should not depend on it.

Some recent versions of the compiler under ARC may be conservative and copy a block immediately after it is created. There is nothing wrong with that. Again, if it does that, it would be an implementation detail, and other compilers or future versions may do something different.

gelosie

I asked a same question at In Objective-C with ARC, what does compiler do when I define a block?

Case you run the code in ARC

In ARC,

block variables of retainable object owner type are moved off the stack by initializing the heap copy with the result of moving from the stack copy.

in http://clang.llvm.org/docs/AutomaticReferenceCounting.html#blocks

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!