1

My question regards blocks in Objective-C: Assume the following situation (with ARC enabled):

typedef NSString*(^MyBlockType)();
typedef NSString*(^MyReturnBlockType)(MyBlockType);

- (MyReturnBlockType) foo: (MyBlockType) block
{
    return ^NSString*(MyBlockType someBlock) {
        return someBlock();
    };
}

The parameter block that is received by the method foo: is used within the block that is returned by the method. However, who keeps a strong reference to the block? Should foo: copy the block before returning the MyReturnBlockType-block? Any insight would be appreciated.

Nicolas
  • 755
  • 9
  • 22
  • Where are you using block again? is it `block();return someBlock()`? – Jano Sep 04 '13 at 14:25
  • 3
    In your example, the `block` parameter is *not* used. – Martin R Sep 04 '13 at 14:25
  • possible duplicate of [Under ARC, are Blocks automatically copied when assigned to an ivar directly?](http://stackoverflow.com/questions/10453261/under-arc-are-blocks-automatically-copied-when-assigned-to-an-ivar-directly) – Sergey Kalinichenko Sep 04 '13 at 14:26

1 Answers1

1
  1. The parameter block is not used anywhere in your code.

  2. Let's supposed that you meant to use block inside someBlock. Variables of object pointer type captured by a block are retained when the block is copied. Furthermore, variables of block pointer type captured by a block are copied when the block is copied. So, when someBlock is copied, block will be copied.

  3. In ARC, a stack block that is returned directly is automatically copied before returning. Thus, someBlock, and also block, will be caused to be copied.

  4. No, foo: does not need to explicitly copy block, because it is not doing anything to explicitly store it (in an instance variable or something).

newacct
  • 119,665
  • 29
  • 163
  • 224
  • it's a real minor quibble but my interpretation of the documentation re: (2) was that because `block` would be captured when `someBlock` is created, it would be copied then — just as anything else inside would be retained then. No need to wait for `someBlock` to be copied. Do we disagree? – Tommy Sep 04 '13 at 22:28
  • 1
    @Tommy: Yes, we disagree. Captured things are not retained/copied until the block is itself copied. This is true in MRC as well as ARC, except that it is sometimes not obvious in ARC when the block is copied, because the compiler is allowed to add extra copies in any place. – newacct Sep 04 '13 at 23:09
  • that being the case, I've consulted the documentation. That made me agree with you. I subsequently wrote a test program (non-ARC, create a mutable string, create a stack block that attempts to output the string, release the string, perform the block) that confirmed your reading. So thanks for teaching me something. – Tommy Sep 04 '13 at 23:22