1.問題
你知道delegate 如果是strong 修飾的話,就會引起循環(huán)引用得封。導(dǎo)致內(nèi)存釋放不掉埋心,內(nèi)存泄漏。
你知道 :block 里忙上,如果 用到 self 的話拷呆,就必須 先weak self ,如果不用的話就會導(dǎo)致內(nèi)存釋放不掉疫粥,內(nèi)存泄漏茬斧。
但是 你知道 究竟怎么樣 才能檢測到循環(huán)引用 引起的內(nèi)存泄漏嗎?
怎么看我的代碼究竟有沒有 內(nèi)存泄漏梗逮?
2 代碼
下面我們就用Instrument 檢測下 循環(huán)引用项秉。更直觀的感受下。
內(nèi)存檢測代碼:
LeakController 里 調(diào)用 LeakImageView 顯示圖片慷彤。并設(shè)置 LeakImageView 的delegate娄蔼, 注意 LeakImageView 的delegate 并未用weak 引用。會引起循環(huán) 應(yīng)用底哗。
LeakController 預(yù)覽
LeakController 代碼
//
// LeakController.swift
// Cycle
//
// Created by Sunny on 2017/9/29.
// Copyright ? 2017年 Sunny. All rights reserved.
// 簡書: http://www.reibang.com/u/2dc174d83679
import UIKit
class LeakController: UIViewController {
@IBOutlet weak var leakImageView: LeakImageView!
override func viewDidLoad() {
super.viewDidLoad()
// 循環(huán)引用 代碼
leakImageView.delegate = self //注銷 此句 代碼 可以 執(zhí)行deinit岁诉, 否則不執(zhí)行deinit
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
deinit {
print("釋放 LeakController")
}
}
LeakImageView 預(yù)覽
LeakImageView 代碼
//
// LeakImageView.swift
// Cycle
//
// Created by Sunny on 2017/9/29.
// Copyright ? 2017年 Sunny. All rights reserved.
// 簡書: http://www.reibang.com/u/2dc174d83679
import UIKit
class LeakImageView: UIImageView {
/// delegate 強(qiáng)引用 ,delegate 的實(shí)現(xiàn)方式就在此省去跋选。
var delegate : AnyObject? ;
deinit {
print("釋放 leakImageView")
}
}
準(zhǔn)備工作已做好涕癣,現(xiàn)在開始檢測
3.檢測
循環(huán)引用是 因?yàn)椴荒茚尫诺鬡iewController ,所以永遠(yuǎn)不會執(zhí)行 LeakController里的 “deinit” 方法
(1).instrument 啟動(dòng) 選擇APP ,并選擇Allocations野建。
(2).查看 Persistent (持久內(nèi)存)
會發(fā)現(xiàn)Persistent 會從 0 一直漲属划。而且不減。我跳轉(zhuǎn)了11次候生,此處就顯示11同眯。說明 現(xiàn)在存活的LeakController 為 11 個(gè)。但是 正常應(yīng)該是顯示 1 個(gè)唯鸭。
循環(huán)引用的Persistent (如下圖)
注意左下角可以 篩選項(xiàng)目的類须蜗,輸入 《項(xiàng)目名稱》即可篩選項(xiàng)目類
正常的Persistent (如下圖)
Transient(短暫的,路過的) 是 使用過的LeakController目溉;每使用并釋放 一個(gè)Leakcontroller Transient都會增加1. 這個(gè)才是正常的明肮。
總結(jié):
不斷的跳轉(zhuǎn),并返回時(shí): 循環(huán)引用時(shí) Persistent 會一直增長.; 且不會調(diào)用 deinit 方法缭付。
正常情況下 Persistent 是正常使用的個(gè)數(shù)柿估,本項(xiàng)目里是1.且會調(diào)用deinit 方法。