简体   繁体   中英

custom iOS 7 UIViewController transition retain cycle

I'm creating custom transitions in my app and running into two problems. If I set the view controller to handle both UIViewControllerAnimatedTransitioning and UIViewControllerTransitioningDelegate I run into the problem of my view controller never being deallocated. Specifically, this creates the retain:

self.transitioningDelegate = self;

If I don't do that, and put UIViewControllerAnimatedTransitioning and UIViewControllerTransitioningDelegate in a separate NSObject called TransitionController and set it like this:

self.transitioningDelegate = [[TransitionController alloc] init];

the UIViewController is deallocated , but I get memory leaks on the TransitionController object. Does anyone now what I'm doing wrong?

I ran into the same issue and was able to solve it.
The custom transition API is not that well documented and required a lot of trial and error for me to get everything right.

Let me walk you through how I was able to make it work nicely without any memory issues:

Here are the players:

VCA = The view controller that wants to present VCB modally
VCB = The modally presented view controller (presented by VCA)

TC = The custom transition controller object that performs the custom animation.
NSObject subclass that conforms to " UIViewControllerAnimatedTransitioning ".
Will be instantiated within TD.

TD = The custom transition delegate object that provides the transition controller to the system. NSObject subclass that conforms to " UIViewControllerTransitioningDelegate "

Now let's present an instance of VCB

self = an instance of VCA
myModalViewController = is a strong property of self

self.myModalViewController = [[VCB alloc] init];

[self.myModalViewController setModalPresentationStyle: UIModalPresentationCustom];
[self.myModalViewController setTransitioningDelegate: [[TD alloc] init]];
[self presentViewController: self.myModalViewController
                   animated:YES 
                 completion:NULL];

At some point later, VCB asks VCA to be dismissed

self = an instance of VCA
myModalViewController = the modally presented instance of VCB presented earlier

[self dismissViewControllerAnimated:YES 
                         completion:^{
             [self.myModalViewController setTransitioningDelegate: nil]; // DO THIS!!!! 
             self.myModalViewController = nil;
        }];



I hope this helps. It certainly did for me.

In my case I had self ( UIViewController ) holding an instance of a custom UIViewController (lets call it mViewController ), and self is the transitioningDelegate of showing/dismissing mViewConroller . My solution to avoid retain-cycle was to call this inside the .m of mViewController :

-(void)viewDidDisappear:(BOOL)animated {
    self.transitioningDelegate = nil;
    [super viewDidDisappear:animated];
}

Worked like a charm (:

In the second try, you are allocating a TransitionController instance and it will be never released (as nobody has a reference to it). The objects should never retain it's delegates in Objective-C, so you need to have reference to your ViewController and to it's delegate from an other point of your code.

The UIViewControllerAnimatedTransitioning object is retained by the 'from' VC after the transition finishes in iOS7 (this doesn't happen in iOS8) which can cause memory leaks if your transition object stores anything in properties. This bit me in the past, something to be careful of.

In my case, what was causing the retention of my presented view controller was that I was passing the wrong boolean to the completion block of my animation.

[transitionContext completeTransition:transitionContext.transitionWasCancelled];

It should have been this:

BOOL successful = transitionContext.transitionWasCancelled == NO;
[transitionContext completeTransition:successful];

Splitting the code into two lines helps readability.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM