How to avoid retain cycle with delaying block invocation on iOS

做~自己de王妃 提交于 2019-12-08 04:02:07

问题


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.


回答1:


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.



来源:https://stackoverflow.com/questions/15487549/how-to-avoid-retain-cycle-with-delaying-block-invocation-on-ios

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!