在ARC中,我们需要在UIAnimationBlocks中使用__weak self吗?

29

在UIAnimation块中,我们需要使用__weak self吗?如果我们没有将self声明为weak,它是否会创建内存泄漏的问题?

[UIView animateWithDuration:animationDuration 
                      delay:0 
                    options:UIViewAnimationCurveEaseInOut 
                 animations:^{
        [self doSomething];
    } completion:^(BOOL finished) {
        if (finished) {
            [self doSomething];
        }
    }];

我在下列情况中也感到困惑。你对此有什么想法吗?请分享你的评论。

[self.navController dismissViewControllerAnimated:animated 
                                       completion:^{
                                                      [self doSomething];
                                                  }];

我们应该在这里使用 weak self 吗?


谢谢大家,我越来越清楚了。我也想讨论以下这个案例。[self.navController dismissViewControllerAnimated:animated completion:^{ [self doSomething]; }]; - arango_86
3个回答

65

这不是一个保留循环。 一个保留循环会是

self -> block -> self

在这种情况下,我们有

animation framework -> block
block -> self

第一个 retain 只是临时的 - 当动画结束时,该块会被释放。即使出现了保留循环,它也只是临时的,不会阻止对象被销毁。


以下是关于下面这个案例的内容:void (^animateBlock)(void) = ^(void){[self doSomething];}; - arango_86
@arango_86 这与您在问题中所写的情况相同。要创建保留循环,您必须首先在对象上创建一个属性,例如 @property (nonatomic, copy) void (^animateBlock)(void),然后将其分配给 self.animationBlock = ^(void){ [self doSomething]; }; - Sulthan
1
在动画中使用 weak self 仍然是好的,这样当视图控制器离开视图时就不会阻止其被释放 - 当视图控制器不再处于视图中时执行动画是没有意义的。 - Boon
2
@Boon 如果视图不在层次结构中,则不会实际执行任何动画并立即调用回调。 - Sulthan
@Sulthan 虽然这样做没有害处,对吧?在 Swift 中,你实际上会从动画块内得到一个 weak self。 - Boon
如果使用UIViewAnimationOptionRepeat选项,那么动画永远不会结束,这会怎样? - Leszek Szary

6

当存在保留循环的可能时,您需要使用__weak。但是,在此情况下,动画块不会由self保留,因此不存在这种情况。

另一种需要使用__weak的情况是,执行长时间操作将在完成后调用我们的块,并且在此操作期间可以释放self。例如,某些网络请求将在完成块中调用界面更新以更新我们的视图控制器。用户可能会在请求期间退出屏幕。在这种情况下,无需使用带有块的retain self,最好使用弱引用的self。但是,在使用动画块时也不是这种情况。


3
不会创建保留循环,因为块(闭包)未附加到self
更多信息,请查看苹果的自动引用计数

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接