
比如有一个 class A ,
是一个 model ,
我在首页加载一批 A 的数据,
当点击某个按钮, push 了一个 view 进来,把其中一个 A 放在 view 的 init 里传进去,
在 view 里暂存了 A,
当点返回, view 的 deinit 被调用,但同时 A 内存泄漏。
我是用了 PleakSniffer ,它显示的说可能内存泄漏,
但本身 A 就是不需要被释放的,因为在首页还需要用。
但如果我在 view 里,对引用 A 的变量设置 weak ,就不会报这个错,
如果真的是因为这样造成泄漏,那我觉得如果我往一个 tableView的 cell 里传我自定义的数据类,
不全得泄漏吗?
难道我都得设置成 weak ?
我写一下示例代码吧,实际我发现加了weak也没什么用。
// 数据类 class A{ var name : String!; var age: Int!; } // 主界面,是一个UINavigationController根视图 class Main: UIViewController{ var data: [A] = []; func loadData(){ // get data A from some web service } // call from some UIButton func buttonPressed(_ sender: UIButton){ let index = sender.tag; let a = self.data[index]; let view = NewViewController(withData: a); self.navigationController?.pushViewController(view, animated: true); } } // 新界面 class NewViewController: UIViewController { let tableView : UITableView!; let data: A!; // 我现在改成下面这样了,也没用 // weak var data: A! init(withData data: A){ self.data = data; } deinit{ print("\(type(of: self)) deinit"); } } 情况就是上面这样的,实际NewViewController里的deinit在返回后是被调用了的,但同时PLeakSniffer报了个Detect Possible Leak: ProjectName.A
然后我在另外一个界面看了一下,情况类似上面的,但那个界面是二级界面,是一个UITableView 但这个界面里的数据,是翻页的,所以没有外部传入的数据,全是自己从服务器加载的,但点击后还是会进入一个详情界面,也就是三级界面,当退回到这个二级界面后,也报了这样的错误,但如果再退回到主界面,所有包含的对象的deinit 都会被调用。 由于开始写的时候 deinit里输出的方式是直接写字符串,后来把基类改成了print("(type(of: self)) deinit"); 子类的没删,都连着输出了两次,可见deinit是按正常顺序执行了的。
所以我也怀疑像各位说的,我的理解就是这些检测工具,应该是类似通过监测deinit的方式,当一个类发生了deinit, 然后就把这个类里的自定义属性枚举一遍,尝试类似canResponseTo之类的操作,如果还是可以可以,就会报Leak。
1 zhongdong 2017-03-16 22:45:47 +08:00 没太明白楼主表达的意思。要查看 view 有没有释放,要看 dealloc 方法有没有调用 |
2 abellee OP @zhongdong 不好意思 我想说的意思其实就是传值,从一个长驻界面,传一下自定义的数据类到新的视图里,新的视图里会暂存一下。 新视图的 deinit 已经被调用了的,我的理解也就是已经释放了。 但传进来的数据类报了可能内存泄漏 |
3 abellee OP @zhongdong push 自定义数据类 长驻界面 -----------------------------------------------> 新界面 pop 新界面的 deinit 被调用,即释放 长驻界面 <----------------------------------------------- 新界面 就这么个过程,但在新界面释放后, PleakSniffer 报了个自定义数据类 可能内存泄漏的提示 |
4 acumen 2017-03-17 00:14:44 +08:00 via iPhone 从引用计数来看,常驻页面持有 A 对象, A 的引用计数 +1 ,此时 A 对象被传到新页面,新页面也持有 A 对象 A 的引用计数再 +1 ,当新页面被 deinit 的时候 A 引用计数 -1 ,最后 A 的引用计数不等于 0 也就是说 常驻页面还持有 A 对象(不知道是不是 lz 表达的意思 |
5 来个 demo 谢谢 |
6 acumen 2017-03-17 00:22:13 +08:00 via iPhone @acumen 内存泄漏通俗地讲是 该释放的没有释放, A 对象不该在新页面 deinit 被释放啊,不算内存泄漏吧 |
7 dangyuluo 2017-03-17 01:46:35 +08:00 内存泄漏往往是密封垫圈老化,更换密封垫圈即可。 |
8 zhongdong 2017-03-17 07:53:37 +08:00 via Android 感觉不是这个 model 造成的内部泄露。要不上个 Demo ? |
9 XDDD 2017-03-17 08:09:08 +08:00 via iPhone 报的是“可能的”内存泄漏,不是已经泄漏了。你的 vc 释放了,但是持有的 model 还在,那不是很可疑吗。在你的例子里,这不是内存泄漏。但是程序并没有这么聪明,查不出来 |
11 eato 2017-03-17 10:34:24 +08:00 via iPhone 来段出问题的代码看看? |
12 XDDD 2017-03-17 12:51:44 +08:00 via iPhone |