我写一下示例代码吧,实际我发现加了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。