zoukankan      html  css  js  c++  java
  • [Swift通天遁地]七、数据与安全-(12)使用Instruments Leaks工具检测内存泄露

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    ➤微信公众号:山青咏芝(shanqingyongzhi)
    ➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
    ➤GitHub地址:https://github.com/strengthen/LeetCode
    ➤原文地址:https://www.cnblogs.com/strengthen/p/10335778.html 
    ➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
    ➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

    目录:[Swift]通天遁地Swift

    本文将演示使用Instruments Leaks工具检测应用程序中的内存泄漏问题。

    内存溢出 out of memory:是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。

    内存泄露 memory leak是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。

    在项目文件夹【DemoApp】上点击鼠标右键,弹出右键菜单。

    【New File】->【Swift File】->【Next】->【Save As】:People.swift->【Create】

     1 import Foundation
     2 //主人类
     3 class People
     4 {
     5     //名称属性
     6     var name : String
     7     //主人的宠物
     8     var pet : Pet?
     9     
    10     //添加一个初始化方法,并以名称作为参数
    11     init(name:String)
    12     {
    13         //设置对象的名称属性
    14         self.name = name
    15         //初始化日志
    16         print("People is initialized.")
    17     }
    18     
    19     //添加一个析构方法
    20     deinit
    21     {
    22         //析构日志
    23         print("People is deinitialized.")
    24     }
    25 }

    使用相同的方式创建另一个类文件【Pet.swift】 

     1 import Foundation
     2 //宠物类
     3 class Pet
     4 {
     5     //名称属性
     6     var name : String
     7     //宠物的主人属性
     8     var master : People?
     9     
    10     //添加一个初始化方法,并以名称作为参数
    11     init(name:String)
    12     {
    13         //设置名称属性
    14         self.name = name
    15         //输出初始化日志
    16         print("Pet is initialized.")
    17     }
    18     
    19     //添加一个析构方法
    20     deinit
    21     {
    22         //析构日志
    23         print("Pet is deinitialized.")
    24     }
    25 }

    在项目导航区,打开视图控制器的代码文件【ViewController.swift】 

     1 import UIKit
     2 
     3 class ViewController: UIViewController {
     4 
     5     override func viewDidLoad() {
     6         super.viewDidLoad()
     7         // Do any additional setup after loading the view, typically from a nib.
     8         
     9         //添加一个按钮,当用户点击该按钮时,创建主人对象和宠物对象。
    10         let button = UIButton(frame: CGRect(x: 0, y: 0,  280, height: 44))
    11         //将按钮控件放置在根视图的中心位置
    12         button.center = self.view.center
    13         //设置正常状态下的标题文字
    14         button.setTitle("PeopleAndPet", for: .normal)
    15         //设置按钮的背景颜色为橙色
    16         button.backgroundColor = UIColor.orange
    17         //给按钮绑定点击事件
    18         button.addTarget(self,
    19                          action: #selector(ViewController.peopleAndPet), 
    20                          for: UIControl.Event.touchUpInside)
    21         
    22         //设置根视图的背景颜色
    23         self.view.backgroundColor = UIColor.orange
    24         //并把按钮控件添加到根视图
    25         self.view.addSubview(button)
    26     }
    27     
    28     //添加一个方法,用来响应按钮的点击事件
    29     @objc func peopleAndPet()
    30     {
    31         //添加一个主人对象和一个宠物对象
    32         var master:People?
    33         var dog:Pet?
    34         
    35         //对两个对象进行初始化操作,并设置它们的名称属性。
    36         master = People(name: "Jerry")
    37         dog = Pet(name: "Dog")
    38         
    39         //设置主人的宠物属性
    40         //设置宠物的主人属性
    41         //使两个对象相互引用,
    42         //由于两个对象互相引用,所以两个对象并不会在内存中被释放。
    43         master!.pet = dog        
    44         dog!.master = master       
    45 
    46         //将两个对象置空
    47         master = nil
    48         dog = nil
    49     }
    50 
    51     override func didReceiveMemoryWarning() {
    52         super.didReceiveMemoryWarning()
    53         // Dispose of any resources that can be recreated.
    54     }
    55 }

    点击【Product】->【Profile】->在弹出的性能分析模块窗口中,选择需要的模块。

    在此选择【Leaks】->【Choose】

    点击左上角的记录按钮,开始运行程序。

    应用程序启动之后,在内存状态时间图谱上,显示了一个泄露图标,点击此图标显示详细的内存信息。

    此时在内存泄露堆栈列表中,显示了产生内存泄露的两个对象。点击选择第一个对象。

    然后点击内存地址右侧的小箭头,显示内存分配的历史记录。

    在此记录中,只看到了记录分配的时间,而没有内存被释放的时间。

    所以也证明了该对象的内存,确认未被释放。

    选择列表中的周期和根选项【Cycles & Roots】,此时显示了内存泄露的周期图。

    从图中可以看出,内存泄露的问题是People对象和Pet对象循环引用造成的。

    选择列表中的调用树选项选项【Call Tree】,

    依次点击标签名称左侧的小箭头,查看内存分配的历史调用记录。

    点击【设置】图标,进行显示选项设置面板。勾选【HideSystem Libraries】隐藏系统库。

    此时只显示了开发者的调用记录,鼠标双击标签名称。显示了详细的代码信息。

    点击左上角的软件图标,返回Xcode。将Pet对象的引用修改为弱引用。

     1 import Foundation
     2 //主人类
     3 class People
     4 {
     5     //名称属性
     6     var name : String
     7     //主人的宠物
     8     //将宠物对象的引用修改为弱引用。
     9     //就不会产生内存泄露的问题。
    10     weak var pet : Pet?
    11     
    12     //添加一个初始化方法,并以名称作为参数
    13     init(name:String)
    14     {
    15         //设置对象的名称属性
    16         self.name = name
    17         //初始化日志
    18         print("People is initialized.")
    19     }
    20     
    21     //添加一个析构方法
    22     deinit
    23     {
    24         //析构日志
    25         print("People is deinitialized.")
    26     }
    27 }

    点击【Product】->【Profile】->【Leaks】->【Choose】

    此时在内存分配时间图谱上,显示的是正确的内存分配和释放图标。

  • 相关阅读:
    RAM调优之日志分析
    HDU Always Cook Mushroom (极角排序+树状数组)
    并非全部的程序猿都适合做技术管理
    HTTP Header具体解释
    Linux 通配符
    寻找正在连接中的网络连接
    hdu 1052 田忌赛马
    linux上电自启动应用程序具体解释
    C++ 中的 const 类型变量
    FileUtil
  • 原文地址:https://www.cnblogs.com/strengthen/p/10335778.html
Copyright © 2011-2022 走看看