Clarification on Apple's Block Docs?

前端 未结 2 1930
挽巷
挽巷 2021-01-07 00:51

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\'s documentation

2条回答
  •  暗喜
    暗喜 (楼主)
    2021-01-07 01:43

    1. 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.

    2. 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.

    3. 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.

    4. 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.

    5. 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.

提交回复
热议问题