我很困惑为什么当我调用removeFromSuperview时,为已删除的视图分配的内存不会被释放。所以这是我的代码和测试结果的一部分。 我有uiscrollview和uiview在uiscrollview上添加。所以当我滚动我的uiscrollview时,我会调用removefromsuperview并期望释放内存。
-(void) someFunction {
magazineContentView = [[MagazineContentView alloc] initWithFrame:CGRectMake(35 + 320 *i ,0,self.view.frame.size.width,self.view.frame.size.height)];
[_scrollView addSubview:magazineContentView];
}
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
[magazineContentView removeFromSuperview];
magazineContentView = nil;
}
magazineContentView被正确删除但内存没有减少。
我没有使用ARC。
感谢。
答案 0 :(得分:1)
当您分配magazineContentView并将其添加为子视图时,它会被保留两次。由于您使用的是手动保留版本,而不使用ARC,因此需要在将其添加为子视图后将其发布。
[magazineContentView removeFromSuperview]
只会将保留计数降低1.由于init调用,仍有一个保留的实例。
(仅供参考你真的不应该介意/考虑保留计数,但我在这里提到它以更好地解释我的答案)。
另外,直接将你的ivar设置为nil,就像你正在做的那样,因为它不是属性所以不会真正有用。
您也不应该在didEndDecelerating调用中从superview中删除。这是不好的做法。您已将其设置为nil,因此调用removeFromSuperview
不会对任何内容造成任何损害,但这不是好的代码设计。
为什么不直接使用ARC?它使用起来更干净。
如果你坚持使用MRR,你应该在将它作为子视图添加后调用magazineContentView上的release。这样,当您稍后调用removeFromSuperview时,保留并释放余额。
-(void) someFunction {
magazineContentView = [[MagazineContentView alloc] initWithFrame:CGRectMake(35 + 320 *i ,0,self.view.frame.size.width,self.view.frame.size.height)];
[_scrollView addSubview:magazineContentView];
[magazineContentView release];
}
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
// Move these to some other place... e.g. a separate method that does this only once
[magazineContentView removeFromSuperview];
magazineContentView = nil;
}
另外,你应该首先密切关注泄漏,然后你应该看一下分配测量。
您是否看过Apple的内存管理指南?阅读本文档并更好地理解MRR是值得投入的时间 - https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html