I have a parent UIView
and an UITextView
as one of the subviews.
And I created a button to dismiss the parent UIView
like this:
-(void)cancelButtonPressed:(UIButton *)sender
{
[UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.frame = CGRectZero;
} completion:^(BOOL finished) {
if (finished) {
[self removeFromSuperview];
}
}];
}
I can tell that the parent UIView
didn't get released because if I typed some text into the UITextView
and dismissed it, when I opened the UIView
again, instead of a blank UITextView
, the SAME text is in it again.
I checked the Leaks
tool but I didn't see any leaking. So I'm guessing if I have some kind of retain cycle or what.
UPDATE:I have another object (which is the AppDelegate
) who is holding the UIView
's instance: _myView
as a global variable like this:
_myView = [[MyView alloc] init];
_myView.nameLabel.text = _user.screen_name;
[_window addSubview:_myView];
[UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
_myView.frame = CGRectZero;
} completion:nil];
But in order to avoid retain cycle, should I create a weak self like this: __weak MyView *weakSelf
and in the animation block do this: [weakSelf removeFromSuperview]
?
I've also tried calling removeFromSuperview
on the view itself, and it doesn't result in the view being released.
If you want to release the view, then go with an approach that uses a delegate. That way, you will be able to call removeFromSuperview
on the view, once the animation is complete, and set it to nil
. This has worked for me in the past.
So, you can add a method to the view class that you want to animate closed, where you will do the animation. Set your view controller as a delegate to your view, and call some method on the delegate, from the completion block of that animation.
You can create your own protocol for this. If you keep it general enough, and focus only on animation callbacks, you can reuse the protocol in all your view controllers.