在块中的WeakSelf

4

关于弱引用、块以及保留循环方面有疑问。

按照规范,我们需要在块中使用弱引用。

那么问题来了,什么时候需要用?

例如,简单的动画代码从未包含弱引用。

比如:

self.myView.alpha = 1.0;
[UIView animateWithDuration:0.2 animations:^{
self.myView.alpha = 1.0; 
}];

这段代码是否正确?或者我应该在块之前创建一个弱引用并在内部使用它?

在我的所有代码和其他项目中,从未看到过一行使用弱引用的代码。现在我正在尝试在每个块中使用弱引用...只是我不确定是否必要。

期待您的意见 谢谢


“只是我不确定是否有必要” - 在某些情况下,防止内存泄漏绝对是必要的。您经常对应用程序进行分析吗?您是否发现内存使用量持续增加?(不要仅依赖于Leaks工具,它并不完美)。如果确实如此,那么您可能存在泄漏问题,如果您正在使用ARC,则这些泄漏几乎总是保留循环。 - James Webster
2个回答

7
当可能存在保留循环时,应使用 weak selfs。
想象一下,foo 的实例对 bar 持有强引用。现在你给 bar 一个块并引用 foo 的 self。现在有人释放了 foo,但 bar 仍持有该块。现在 foo 对 bar 有一个强引用,而该块中 bar 对 foo 也有一个强引用。Foo 将不会被释放,因此也不会释放 bar,因为 bar 正保留着它。但是,唯一保留 bar 的东西是现在未使用的 foo。你创建了一个保留循环,这两个对象现在漂浮在内存中无法访问。
UIView 的动画没有问题,因为该块在 animate: 方法返回之前调用,UIView 不会保留该块。
ARC 通常会在看到可能出现保留循环的情况时发出警告。但并非总是如此。一个好的经验法则是在不知道该块最终去向时使用 weak selfs。
希望这会对您有所帮助。

4
正如其他人所指出的那样,在本来会产生强引用循环(也称为保留循环)的情况下,您应该绝对使用weakSelf模式。但更一般地说,无论是否涉及保留循环,您都应该在不想让块保留对象本身时使用weakSelf

一个很好的例子是由某个视图控制器发起的网络操作。假设用户启动了某个上传。问题是,即使它可能有对该视图控制器的引用以更新某些进度条或类似的东西,您是否希望异步上传过程保留该视图控制器。即使您希望上传继续,您也可能不希望它保留视图控制器,如果视图控制器被解散。

这只是一个随机的例子,但归根结底,您可能希望在需要后台进程继续运行,但不希望其保留其他对象时使用weakSelf模式。只需查看您的功能需求并考虑强引用循环风险,并决定是否需要使用weakSelf模式。

animateWithDuration的情况下,当视图被解散时,动画停止并立即解决强引用,因此不存在强引用循环。


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