比如有一个 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 1
没太明白楼主表达的意思。要查看 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
paradoxs 2017-03-17 00:20:40 +08:00 via iPhone
来个 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
|