Should I still copy/Block_copy the blocks under ARC?

Stanislav Pankevich picture Stanislav Pankevich · Apr 28, 2014 · Viewed 13.8k times · Source

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

Answer

Matt Stevens picture Matt Stevens · Apr 29, 2014

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 a Block_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.