简体   繁体   中英

How to avoid retain cycle with delaying block invocation on iOS

I am really stumped with this one. I have been reading all the info I can get my hands on about how to properly handle variables inside blocks.

Note: I am not using arc.

So, say I have an animation that looks like this:

[UIView animateWithDuration:.5 animations:^{
    textCard.alpha = 1.f;
    self.dotView.alpha = 1.f;
    self.subtitles.alpha = 0;
}completion:^(BOOL finished){
    [self.playerLayer removeFromSuperlayer];
    self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.vidPlayer];
    self.playerLayer.frame = self.vidView.bounds;
    [self.vidView.layer insertSublayer:self.playerLayer atIndex:0];
    [self.subtitles removeFromSuperview];
    self.subtitles = [sub autorelease];

    [UIView animateWithDuration:.3 delay:1 options:UIViewAnimationOptionAllowUserInteraction animations:^{
        textCard.alpha = 0.f;
        sub.alpha = 1.f;
    }completion:^(BOOL finished){
        self.queuedVid = NO;
        if (self.shouldPlay == YES) {

            [self.vidPlayer play];
            [self setCurrentVideoSettings];
        }
        else{
            self.shouldPlay = YES;
        }

        [textCard removeFromSuperview];
        textCard = nil;
    }];
    }];

Now this code probably looks a little arbitrary but here is a very real world example of something I have to do.

Here are my two problems:

  1. If I leave this as is and the class (tries) to get deallocated during the invocation of this block, it will not release.

  2. If I change self to __block typeof (self) weakRef = self; then if the class gets deallocated before the second block can run, it crashes because it is trying to reference my deallocated self.

I know I just must not understand how this works, but if anyone can shed some light, I would appreciate it.

You shouldn't worry about retain cycles created by references to self in inline animation blocks. The block will retain self when the animation begins, and release it when the animation block finishes executing.

Imagine someone does something that invokes your animation. Then, before the animation completes, they pop that view controller off the navigation stack. The navigation controller releases your controller, but the animation block continues to retain it. When the animation completes (off screen), the block will release what should be the last reference to your controller, and it will be deallocated.

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