I am capturing a method-scoped object in a C block and I want to avoid retain cycles. Here is my code: (balloon
is a custom view created within my current method)
balloon.onAddedToViewHierarchy = ^{
CGRect globalRect = [[UIApplication sharedApplication].keyWindow convertRect:self.frame fromView:self.superview];
CGRect targetFrame = CGRectMake(20, 0, SCREEN_WIDTH - 40, 60);
targetFrame.origin.y = below ? globalRect.origin.y + globalRect.size.height + 10 : globalRect.origin.y - 10 - 60/*height*/;
balloon.frame = globalRect;//targetFrame;
};
at the last line (balloon.frame = globalRect;
) I am told that capturing balloon
in block will lead to a retain cycle. I know about ARC, ownerships, retain counts etc and I know the reason. I am just looking for a way to implicitly get rid of retaining balloon
(it's already guaranteed to be retained by being referenced from other places) and using a __weak
pointer, or __block
if appropriate. I know I can do this:
__weak UIView *weakBalloon = balloon;
balloon.onAddedToViewHierarchy = ^{
CGRect globalRect = [[UIApplication sharedApplication].keyWindow convertRect:self.frame fromView:self.superview];
CGRect targetFrame = CGRectMake(20, 0, SCREEN_WIDTH - 40, 60);
targetFrame.origin.y = below ? globalRect.origin.y + globalRect.size.height + 10 : globalRect.origin.y - 10 - 60/*height*/;
weakBalloon.frame = globalRect;//targetFrame;
};
But actually I'm exploring ways to implement the same behavior without explicitly creating a new pointer. I am looking for something like this: (it won't compile, just a demo)
balloon.onAddedToViewHierarchy = ^{
CGRect globalRect = [[UIApplication sharedApplication].keyWindow convertRect:self.frame fromView:self.superview];
CGRect targetFrame = CGRectMake(20, 0, SCREEN_WIDTH - 40, 60);
targetFrame.origin.y = below ? globalRect.origin.y + globalRect.size.height + 10 : globalRect.origin.y - 10 - 60/*height*/;
((__weak UIView*)balloon).frame = globalRect;//targetFrame;
};
Is something similar possible? I know there's nothing wrong with declaring a __weak
variable, it will just work perfectly. I'm just curious that if such an implicit behavior is possible or not.
Consider using the
@weakify
and@strongify
macros, included in Reactive Cocoa or the Extended Objective-C Library.For demonstration of this, see the Avoiding Retain Cycles discussion in Ray Wenderlich's part 2 of 2 discussion about Reactive Cocoa.
That article provides the following example:
Which they go on to suggest could be replaced with: