因此,在花时间寻找内存管理问题时,经过深思熟虑和一些挫折,我做了一些研究,最终还是选择了ARC。这相对来说是无痛的。然而,一个新的问题出现了,与我的UIViewControllers有关,Pre-arc它们都像广告中说的那样工作,我把它们推到堆栈上,它们出现了,我把他们从堆栈中弹出,他们的dealloc方法被调用了,每个人都很高兴。切换到ARC,永远不会调用dealloc。这是不幸的。所以我对这个问题做了一些研究,让我列出我正在做什么和/或没有做
。首先,我推送到堆栈上的视图没有明确声明为强视图。
.子类拥有的父类的委托是不可保留的,但为了覆盖基,我甚至评论了将委托设置为父类,没有乐趣。
.关闭NS僵尸,因为这显然会导致ARC启用代码中的东西滞留
.根据brad larsons在内存中的回答,我更改了我的代码,而不是在ios视图层次结构中发布的,从这个
if (_friendsListVC == nil)
{
_friendsListVC = [[FriendsListViewController alloc] initWithNibName:nil bundle:nil];
_friendsListVC.delegate = self;
}
[self.navigationController pushViewController:_friendsListVC animated:YES];
(_friendsListVC是一个成员变量)。到此
FriendsListViewController *fVC = [[FriendsListViewController alloc] initWithNibName:nil bundle:nil];
//fVC.delegate = self;
[self.navigationController pushViewController:fVC animated:YES];
Joy,dealloc断点永远不会被击中,问题是我在我的应用程序中推送和弹出了很多视图,所以这只会导致更多的内存问题,除了我改为ARC希望解决的问题之外。。。
还要注意,我在这个视图中有一些代码块,还有一些其他代码块,但我不使用self,我也读到了self是自保留的,所以当涉及到代码块时,你应该弱ref。
我很困惑,有人能解释一下ARC在做什么吗?或者我在使用ARC时没有做什么?为了将来参考,你想推到ARC中视图层次结构上的所有视图都不是实例变量吗?
提前谢谢。
我弄清楚了问题是什么,但它并没有修复没有被释放的OTHER控制器,这些控制器完全是由于不同的原因。因此,为了传播知识并减轻其他人的痛苦,我将列出可能导致保留周期的事情的数量,主要与ARC和UIViewControllers以及代码块有关
-
不要强烈引用你正在推动的视图。
-
如果你推送到视图层次结构上的类有一个调用push方法的类的委托,使其成为一个不可恢复的引用,事实上,最好使你的所有委托都不可恢复,因为我的一个委托很强,因为我认为ARC转换器会为我做这件事。
-
关闭NSZombies。请不要介意,只是在需要确保dealloc语句在应该调用的时候调用。
-
不要在代码块中直接引用self,这会导致保留循环。如果您需要使用self,请在块外执行以下操作(然后使用weakself)
__unsained_sunsafe className*weakSelf=self;
-
小心静态引用,我对此不确定,但我有一个方法,它接受了两个实例化的视图控制器,并将一个推到另一个之上,这些引用被分配给了这个类中的两个静态实例(不要问为什么),在使用后将它们归零似乎解决了我的问题,我不确定为什么。
-
这是另一个我不确定的问题,但我在某个地方看到过一两次,如果你在一个类中有一个代码块,尽量不要在该块中使用实例变量,再次使变量__unsafe_unretained。
仅此而已,在检查并修复了其中的大多数之后,我的所有视图在每次推送时都会调用它们的dealloc方法,而不是在某个奇怪的任意点。此外,为了澄清这只是一个简短的清单,可以快速帮助任何面临同样问题的人,我并不声称对这里的一些概念有充分的理解,但我建议你应该这样做,因为我希望及时这样做。
这正是Instruments存在的原因。运行Leaks工具,它会告诉你是什么分配了这些视图控制器(你已经知道了),以及我要保留它们的其他内容(你不知道)。
此外,您声称存在内存泄漏,但直到您运行ObjectAlloc仪器并看到内存使用率随着重复使用而实际攀升,您才知道这一点。
我遇到了同样的问题。
当我在项目中禁用NSZombie
选项时,它对我有效。我不知道为什么会发生这种情况。
- 转到ProductEdit方案
- 禁用NSZombie