How many readers of this blog know that Objective-C blocks are initially created on the stack, unlike every other type of Objective-C object? I believe this is for performance reasons.
It used to be a bigger deal, before ARC. Why? Because those stack-based blocks would be deallocated once their scope ended. If you tried to reference a stack-based block outside its enclosing scope, your app would crash and burn.
To get around this, you had to send a
copy message to the block, which would perform a special sort of copy to copy it to the heap instead, like every other Objective-C object. Then it could be passed around, because it wasn’t tied to the stack’s scope anymore. Of course, then you’d also be on the hook for sending it a
release message, or you’d have a memory leak.
That’s why, if you have a block property, you’re supposed to use the
copy attribute, not the
typedef void (^MyBlock)(); @interface MyClass : NSObject @property (nonatomic, copy) MyBlock myBlock; @end
All that’s water under the bridge with ARC, however.
ARC adds those
copy calls for you, in the same way that it adds
release calls for regular Objective-C objects. You’ll never have to worry about using a stack-based block outside of its scope accidentally, because ARC will never let you do that.
The result? Now, when I mention the dangers of stack-based blocks to my younger coworkers, they have no idea what I’m talking about.