This is a bit of a tricky scenario. I've been studying blocks and started implementing them for the first time, and I found myself wanting to create a "compound block". Here's my code, roughly:
- (void)moveToPosition:(NSInteger)pos withVelocity:(CGFloat)vel onCompletion:(void(^)(BOOL completed))completionBlock
{
void (^compoundBlock) (BOOL completed) = ^(BOOL completed) {
[self unlockInteractionFromPullDownMenuTab];
void(^innerCompletionBlock)(BOOL completed) = completionBlock;
innerCompletionBlock(completed);
};
// Animate
[UIView animateWithDuration: duration
animations: ^void{ [self.pullDownMenu setFrame:newFrame]; }
completion: compoundBlock
];
}
The goal is to take a block of code that is passed into this method, add something to it, and then pass it into an animation method call. However, I get a bad access on the line:
innerCompletionBlock(completed);
I figure that my innerCompletionBlock is getting deallocated, but I'm not entirely sure why. From what I understand, blocks copy everything that you throw at them, including references to self--which can create retain cycles, and which I recently learned to avoid.
Actually, I originally tried this:
void (^compoundBlock) (BOOL completed) = ^(BOOL completed) {
[self unlockInteractionFromPullDownMenuTab];
completionBlock(completed);
};
But I was getting the bad access, and I figured that perhaps the compoundBlock wasn't copying the completionBlock, so I explicitly declared a (block) variable inside the block and assigned it to try to get it to retain (perhaps a bit silly, but I'm running under ARC so I can't do manual retain calls).
Anyway, clearly the compoundBlock is being retained when it's passed to UIView, but I'm unsure how to retain my onCompletion/innerCompletionBlock within the compoundBlock since I'm running under ARC.
Thanks in advance :)