【问题标题】:How to avoid retain cycle with delaying block invocation on iOS如何通过延迟 iOS 上的块调用来避免保留周期
【发布时间】:2013-03-18 21:45:11
【问题描述】:

我真的被这个难住了。我一直在阅读有关如何正确处理块内变量的所有信息。

注意:我没有使用 arc。

所以,假设我有一个看起来像这样的动画:

[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;
    }];
    }];

现在这段代码可能看起来有点随意,但这是我必须做的一个非常真实的例子。

这是我的两个问题:

  1. 如果我保持原样,并且在调用此块期间(尝试)释放类,它将不会释放。

  2. 如果我将 self 更改为 __block typeof (self) weakRef = self;,那么如果类在第二个块可以运行之前被释放,它会崩溃,因为它试图引用我释放的 self。

我知道我一定不明白这是如何工作的,但如果有人能解释一下,我将不胜感激。

【问题讨论】:

  • 你的两个问题不兼容。动画块延长了self 的生命周期,或者self 在中间死亡,动画块开始引用垃圾对象。第一个“问题”通常被认为是一个特性。
  • @KevinBallard 延长寿命就好了。但不能完全阻止它解除分配。我不确定您所说的“垃圾对象”是什么意思,因为我没有使用弧。它只是崩溃。我需要某种方式来取消块调用,或者......我需要我的变量在尝试调用时以某种方式返回 nil,以避免崩溃。
  • 它不会阻止对象被释放。一旦完成块被触发,它就会删除对self 的引用,从而释放它。如果您看到对象 never 被释放,那么您还有其他事情发生。
  • “垃圾对象”表示对象“self”是指向内存位置的指针。当对象被释放时,该内存位置可能会被任意数据覆盖,即。垃圾。
  • @KevinBallard 我不明白积木是如何工作的。现在这对我来说很有意义。所以问题是在延迟调用中我告诉我的电影播放器​​播放。我解决了这个问题,现在我的班级在块完成后立即解除分配。

标签: ios objective-c memory-management objective-c-blocks uiviewanimation


【解决方案1】:

您不必担心内联动画块中引用 self 所创建的保留循环。该块将在动画开始时保留自身,并在动画块执行完毕时释放它。

想象有人做了一些调用你的动画的事情。然后,在动画完成之前,他们将该视图控制器从导航堆栈中弹出。导航控制器释放您的控制器,但动画块继续保留它。当动画完成时(屏幕外),该块将释放对控制器的最后一个引用,并将被释放。

【讨论】:

  • 感谢您的解释。我在 Kevin Ballard 的 cmets 的帮助下解决了这个问题。
猜你喜欢
  • 1970-01-01
  • 2016-11-03
  • 1970-01-01
  • 1970-01-01
  • 2012-02-03
  • 2013-09-04
  • 1970-01-01
  • 2021-12-18
  • 1970-01-01
相关资源
最近更新 更多