hzxu
hzxu

Reputation: 5823

iOS: method returns a block then the block is stored in array, when should I copy it?

I have a method that returns a block and another method which uses the method:

- (MyBlock)blockForParameter:(id)param
{
    MyBlock theBlock = ^(){NSLog(@"Param: %@", param);};
    return theBlock;
}

- (void)methodUser
{
    MyBlock theBlock = [self blockForParameter:something];
    [self.allBlocks addObject:theBlock];
}

The question is, when should I copy the block? Should I copy the block when I return it in blockForParameter, or should I copy it when I add it to the array?

Thanks

Upvotes: 5

Views: 1687

Answers (2)

newacct
newacct

Reputation: 122439

Look at each method separately.

In -blockForParameter:, the block literal is returned from the method. The block must be copied in order to outlive the scope of the literal. In MRC, you would need to return the block copied and autoreleased. In ARC, you don't need to do anything.

In -methodUser, the block is not defined in that method; it is received from a method call. Thus, it must have already been copied (i.e. it is not a stack block). Thus, you do not need to do anything with it when you do addObject: to it.

Upvotes: 1

Martin R
Martin R

Reputation: 539705

Blocks must be copied if they "outlive the scope in which they were created", so you must copy the block in your blockForParameter method, before returning it.

Edit: With ARC, this is no longer true. See for example Objective-C: blocks in ARC and the references therein:

  • Returning a block from a function does not require to copy the block.
  • Adding a block to a collection does require a block copy.

Upvotes: 3

Related Questions