Reputation: 5823
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
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
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:
Upvotes: 3