[Swift通天遁地]七、数据与安全-(12)使用Instruments Leaks工具检测内存泄露
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
?微信公眾號(hào):山青詠芝(shanqingyongzhi)
?博客園地址:山青詠芝(https://www.cnblogs.com/strengthen/)
?GitHub地址:https://github.com/strengthen/LeetCode
?原文地址:https://www.cnblogs.com/strengthen/p/10335778.html?
?如果鏈接不是山青詠芝的博客園地址,則可能是爬取作者的文章。
?原文已修改更新!強(qiáng)烈建議點(diǎn)擊原文地址閱讀!支持作者!支持原創(chuàng)!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
目錄:[Swift]通天遁地Swift
本文將演示使用Instruments Leaks工具檢測(cè)應(yīng)用程序中的內(nèi)存泄漏問(wèn)題。
內(nèi)存溢出 out of memory:是指程序在申請(qǐng)內(nèi)存時(shí),沒(méi)有足夠的內(nèi)存空間供其使用,出現(xiàn)out of memory;比如申請(qǐng)了一個(gè)integer,但給它存了long才能存下的數(shù),那就是內(nèi)存溢出。
內(nèi)存泄露 memory leak:是指程序在申請(qǐng)內(nèi)存后,無(wú)法釋放已申請(qǐng)的內(nèi)存空間,一次內(nèi)存泄露危害可以忽略,但內(nèi)存泄露堆積后果很?chē)?yán)重,無(wú)論多少內(nèi)存,遲早會(huì)被占光。
在項(xiàng)目文件夾【DemoApp】上點(diǎn)擊鼠標(biāo)右鍵,彈出右鍵菜單。
【New File】->【Swift File】->【Next】->【Save As】:People.swift->【Create】
1 import Foundation 2 //主人類(lèi) 3 class People 4 { 5 //名稱(chēng)屬性 6 var name : String 7 //主人的寵物 8 var pet : Pet? 9 10 //添加一個(gè)初始化方法,并以名稱(chēng)作為參數(shù) 11 init(name:String) 12 { 13 //設(shè)置對(duì)象的名稱(chēng)屬性 14 self.name = name 15 //初始化日志 16 print("People is initialized.") 17 } 18 19 //添加一個(gè)析構(gòu)方法 20 deinit 21 { 22 //析構(gòu)日志 23 print("People is deinitialized.") 24 } 25 }使用相同的方式創(chuàng)建另一個(gè)類(lèi)文件【Pet.swift】?
1 import Foundation 2 //寵物類(lèi) 3 class Pet 4 { 5 //名稱(chēng)屬性 6 var name : String 7 //寵物的主人屬性 8 var master : People? 9 10 //添加一個(gè)初始化方法,并以名稱(chēng)作為參數(shù) 11 init(name:String) 12 { 13 //設(shè)置名稱(chēng)屬性 14 self.name = name 15 //輸出初始化日志 16 print("Pet is initialized.") 17 } 18 19 //添加一個(gè)析構(gòu)方法 20 deinit 21 { 22 //析構(gòu)日志 23 print("Pet is deinitialized.") 24 } 25 }在項(xiàng)目導(dǎo)航區(qū),打開(kāi)視圖控制器的代碼文件【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 //添加一個(gè)按鈕,當(dāng)用戶點(diǎn)擊該按鈕時(shí),創(chuàng)建主人對(duì)象和寵物對(duì)象。 10 let button = UIButton(frame: CGRect(x: 0, y: 0, width: 280, height: 44)) 11 //將按鈕控件放置在根視圖的中心位置 12 button.center = self.view.center 13 //設(shè)置正常狀態(tài)下的標(biāo)題文字 14 button.setTitle("PeopleAndPet", for: .normal) 15 //設(shè)置按鈕的背景顏色為橙色 16 button.backgroundColor = UIColor.orange 17 //給按鈕綁定點(diǎn)擊事件 18 button.addTarget(self, 19 action: #selector(ViewController.peopleAndPet), 20 for: UIControl.Event.touchUpInside) 21 22 //設(shè)置根視圖的背景顏色 23 self.view.backgroundColor = UIColor.orange 24 //并把按鈕控件添加到根視圖 25 self.view.addSubview(button) 26 } 27 28 //添加一個(gè)方法,用來(lái)響應(yīng)按鈕的點(diǎn)擊事件 29 @objc func peopleAndPet() 30 { 31 //添加一個(gè)主人對(duì)象和一個(gè)寵物對(duì)象 32 var master:People? 33 var dog:Pet? 34 35 //對(duì)兩個(gè)對(duì)象進(jìn)行初始化操作,并設(shè)置它們的名稱(chēng)屬性。 36 master = People(name: "Jerry") 37 dog = Pet(name: "Dog") 38 39 //設(shè)置主人的寵物屬性 40 //設(shè)置寵物的主人屬性 41 //使兩個(gè)對(duì)象相互引用, 42 //由于兩個(gè)對(duì)象互相引用,所以兩個(gè)對(duì)象并不會(huì)在內(nèi)存中被釋放。 43 master!.pet = dog 44 dog!.master = master 45 46 //將兩個(gè)對(duì)象置空 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 }點(diǎn)擊【Product】->【Profile】->在彈出的性能分析模塊窗口中,選擇需要的模塊。
在此選擇【Leaks】->【Choose】
點(diǎn)擊左上角的記錄按鈕,開(kāi)始運(yùn)行程序。
應(yīng)用程序啟動(dòng)之后,在內(nèi)存狀態(tài)時(shí)間圖譜上,顯示了一個(gè)泄露圖標(biāo),點(diǎn)擊此圖標(biāo)顯示詳細(xì)的內(nèi)存信息。
此時(shí)在內(nèi)存泄露堆棧列表中,顯示了產(chǎn)生內(nèi)存泄露的兩個(gè)對(duì)象。點(diǎn)擊選擇第一個(gè)對(duì)象。
然后點(diǎn)擊內(nèi)存地址右側(cè)的小箭頭,顯示內(nèi)存分配的歷史記錄。
在此記錄中,只看到了記錄分配的時(shí)間,而沒(méi)有內(nèi)存被釋放的時(shí)間。
所以也證明了該對(duì)象的內(nèi)存,確認(rèn)未被釋放。
選擇列表中的周期和根選項(xiàng)【Cycles & Roots】,此時(shí)顯示了內(nèi)存泄露的周期圖。
從圖中可以看出,內(nèi)存泄露的問(wèn)題是People對(duì)象和Pet對(duì)象循環(huán)引用造成的。
選擇列表中的調(diào)用樹(shù)選項(xiàng)選項(xiàng)【Call Tree】,
依次點(diǎn)擊標(biāo)簽名稱(chēng)左側(cè)的小箭頭,查看內(nèi)存分配的歷史調(diào)用記錄。
點(diǎn)擊【設(shè)置】圖標(biāo),進(jìn)行顯示選項(xiàng)設(shè)置面板。勾選【HideSystem Libraries】隱藏系統(tǒng)庫(kù)。
此時(shí)只顯示了開(kāi)發(fā)者的調(diào)用記錄,鼠標(biāo)雙擊標(biāo)簽名稱(chēng)。顯示了詳細(xì)的代碼信息。
點(diǎn)擊左上角的軟件圖標(biāo),返回Xcode。將Pet對(duì)象的引用修改為弱引用。
1 import Foundation 2 //主人類(lèi) 3 class People 4 { 5 //名稱(chēng)屬性 6 var name : String 7 //主人的寵物 8 //將寵物對(duì)象的引用修改為弱引用。 9 //就不會(huì)產(chǎn)生內(nèi)存泄露的問(wèn)題。 10 weak var pet : Pet? 11 12 //添加一個(gè)初始化方法,并以名稱(chēng)作為參數(shù) 13 init(name:String) 14 { 15 //設(shè)置對(duì)象的名稱(chēng)屬性 16 self.name = name 17 //初始化日志 18 print("People is initialized.") 19 } 20 21 //添加一個(gè)析構(gòu)方法 22 deinit 23 { 24 //析構(gòu)日志 25 print("People is deinitialized.") 26 } 27 }點(diǎn)擊【Product】->【Profile】->【Leaks】->【Choose】
此時(shí)在內(nèi)存分配時(shí)間圖譜上,顯示的是正確的內(nèi)存分配和釋放圖標(biāo)。
轉(zhuǎn)載于:https://www.cnblogs.com/strengthen/p/10335778.html
總結(jié)
以上是生活随笔為你收集整理的[Swift通天遁地]七、数据与安全-(12)使用Instruments Leaks工具检测内存泄露的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ERROR: SampleCB() -
- 下一篇: opencv 文件模块 解析