I've just stumbled over the following SO topic: Why should we copy blocks rather than retain? which has the following sentence:
However, as of iOS 6 they are treated as regular objects so you don't need to worry.
I was really confused by this assertion that is why I am asking: does this assertion really imply that Objective-C developers do not need to
@property (copy) blockProperties
or
[^(...){...) {} copy]
to copy blocks and their contents from stack to heap anymore?
I hope the description I've made is clear.
Please, be verbose.
Similar questions
Under ARC, are Blocks automatically copied when assigned to an ivar directly?.
ARC will copy the block automatically. From clang's Objective-C Automatic Reference Counting documentation:
With the exception of retains done as part of initializing a
__strong
parameter variable or reading a__weak
variable, whenever these semantics call for retaining a value of block-pointer type, it has the effect of aBlock_copy
. The optimizer may remove such copies when it sees that the result is used only as an argument to a call.
So blocks used only as arguments to function or method calls may remain stack blocks, but otherwise anywhere that ARC retains the block it will copy the block. This is implemented by the compiler emitting a call to objc_retainBlock()
, the implementation for which is:
id objc_retainBlock(id x) {
return (id)_Block_copy(x);
}
It is still a good idea to declare block properties as having copy semantics since a block assigned to a strong property will in fact be copied. Apple recommends this as well:
You should specify copy as the property attribute, because a block needs to be copied to keep track of its captured state outside of the original scope. This isn’t something you need to worry about when using Automatic Reference Counting, as it will happen automatically, but it’s best practice for the property attribute to show the resultant behavior.
Note that since this copy-on-retain feature is provided by ARC it is dependent only on ARC or ARCLite availability and does not otherwise require a particular OS version or OS_OBJECT_USE_OBJC
.