使用Xcode Instruments Leak检测内存泄漏

首先我们先写一段有问题的代码,然后运行一次使App安装在手机或模拟器上,然后Xcode=>Open Developer Tool=>Instruments打开Instruments面板,选择Leaks。

import UIKit


class Person{
    var assets=[Asset]()
    
    func takeAsset(asset:Asset){
        asset.owner=self
        assets.append(asset)
    }
}

class Asset{
    var owner:Person?
}


class MainViewController: UIViewController {
    @IBOutlet weak var testButton: UIButton!
 
    override func viewDidLoad() {
        super.viewDidLoad()
        //申请了内存但是不释放
        let _=UnsafeMutablePointer<Int>.allocate(capacity: 100)
    }
    
    @IBAction func testButtonDidClick(_ sender: Any) {
        //循环强引用
        let person=Person()
        let asset=Asset()
        person.takeAsset(asset: asset)
    }
 
}

点击左上角的红色圆点即可开始内存泄露检测,Leak Checks上方的All Heap & Anonymous VM是内存分配情况,当Leak Checks出现红色叉叉时说明有内存泄露,鼠标点击Leak Checks可以看到内存泄露信息。

Leaks by Backtrace可以看到泄露的对象,地址,大小以及栈回溯,Cycles & Roots可以更直观地看到内存泄露和循环引用情况,Call Tree里显示的是泄露内存分配时的栈回溯,上述三处都有栈回溯,但并不是每次都有。

使用Xcode Instruments Leak检测内存泄漏_第1张图片
看不到栈回溯不好定位出问题的代码,我们可以记录泄露的内存地址,然后在Allocations List中找到该地址查看栈回溯,如果栈回溯里显示的是代码地址而不是函数名,这通常是找不到符号名称导致的,可以尝试在Build Settings中设置Debug Infomation Format为DWARF with dSYM File。
使用Xcode Instruments Leak检测内存泄漏_第2张图片
另外Call Tree有几个选项可以方便我们查看栈回溯:

  • Separate by Thread:将栈回溯按照线程分离
  • Invert Call Tree:将栈回溯顺序颠倒
  • Hide System Libraries:隐藏系统栈回溯
  • Flatten Recursion:将递归调用合并成一个

你可能感兴趣的:(iOS)