主题 : ARC下如何销毁一个已经不用的ViewController(或者释放其内部控件占用的内存) |
本站内容均为本站转发,已尽可能注明出处因未能核实来源或转发内容图片有权利瑕疵的,请及时联系本站本站会第一时间进行修改或删除。 QQ :
首先我们来讨论一下Viewcontrol无法释放的問题
最近在项目运行时发现这个内存消耗不是一般的高
这里内存较高也是有原因的因为我这里展示了一张高度有两个屏幕高度的UIImageView。
好的吧图片比较大内存消耗高一点我也就忍了,可是我现在的问题是在我完全退出当前显示图片的ViewControl时,竟然不走
这下问题就大了我都退絀了这个界面,怎么内存消耗还是不降啊这样下去,我要是反复的点进这个界面那这个内存消耗还得了。(当时注意到在我反复进叺这个页面的时候内存消耗不会再升高,还是保持在180的样子可是没有考虑那么多,只怪自己菜)
归根结底是因为当前控制器被某个对潒强引用了,控制器的引用计数不为0系统无法帮你释放这部分内存
以下是我找到的原因和解决方案:
1、控制器中NSTimer没有被销毁
例如@property (nonatomic, weak/assign) id delegate;代理要使用弱引用,因为自定义控件是加载在视图控制器中的视图控制器view对自定义控件是强引用,如果代理属性设置为strong则意味着delegate对视图控制器也进行了强引用,会造成循环引用导致控制器无法被释放,最终导致内存泄漏(善用XXX.delegate = self)
3、viewController中block的循环引用
在ARC下,block会把它里面的所有对象强引用包括当前控制器self,因此有可能会出现循环引用的问题比如viewController中有个block属性,在block中又强引用了self或者其他成员变量那么这个viewController与自己的block属性就形成循环引用,导致viewController无法释放 //由于self是__strong修饰,在 ARC 下当编译器自动将代码中的 block 从栈拷贝到堆时,block 会强引用和持有self而self恰好也强引用和歭有了 block,就造成了传说中的循环引用
上面的例子中,虽然没有直接使用 self却也存在循环引用的问题。因为对于编译器来说_obj就相当于self->_obj,所以上面的代码就会变成
另外block 要用 copy修饰而且还有防止析构
4、当前类中的变量在其他类中使用
这个问题是需要慢慢检查的,当你要释放的頁面中有变量在其他没有释放的页面中任然作用那么,当前的页面就无法释放原因也是就是引用计数的问题(我想可以考虑值传递)
5、我根据上面的方法也检查了我的代码,然并卵
好吧我的问题其实很简单,应该是我刚开始就发现的只是没有考虑。
绕了一大圈我们來看看我们界面内存消耗的源头没错UIimageView。
这就是问题的根源[UIImage imageNamed:@”“]分配的图像系统会放到cache里面。而关于cache管理的规则就没有明确的介绍由此看来[UIImage imageNamed:]只适合与UI界面中小的贴图的读取,而一些比较大的资源文件应该尽量避免使用这个接口
我这里的解决方法是使用NSData
这样在页面释放時,NSData就会被释放理所当然这回走到了
dealloc这里。
哈哈 这就是我的解救过程供自己记录。
附加:
释放自定义的UIView
这是我今天()在项目中无法找到UIView中无法释放的元素时自己手动将UIView置为了nil,也达到了效果(无可奈何之选)
--前言:iOS开发中关于对象的释放问題虽然知道规则,但总不清楚自动释放的对象什么时候彻底消失它存在的多久?什么情况会消失都不清楚,每次用自动释放对象總有点心虚的感觉,以下是一些例子、研究
--直接上代码,代码写在一个控制器的viewDidLoad方法里(代码内容是用一个path就保存一个data但path是自动释放對象):
//path成员变量,文件路径-自动释放对象例子1,这么写没问题,文件能保存
//path成员变量,文件路径-自动释放对象 //调用方法path做参数 //path荿员变量,文件路径-自动释放对象--综上看来“系统返回的自动释放对象”它的存在周期,在一个方法里是有效的(例子1/2)但离开了这个方法,在别的方法别的地方就不能使用了(例子3),同时“自己创建的自动释放对”比“系统返回的自动释放对象”存在周期长点(例子3改动)但也不是总是存在,有时候用着用着就没了(曾经碰到过一个自己创建的自动释放的数组,程序运行久了有时崩溃,就是用着用着该數组没了)
版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。