Swift5.1學習隨筆之內存管理

OC一樣缺谴,swift也是采取基于引用計數(shù)的ARC內存管理方案(針對堆空間)

swift中的ARC3種引用:

  • 強引用:默認都是強引用
  • 弱引用:通過weak定義弱引用
    1. 必須是可選類型的var朝扼,因為實例銷毀后城榛,ARC會自動將弱引用設置為nil
    2. ARC自動給弱引用設置nil時疮装,不會觸發(fā)屬性觀察器
  • 無主引用:通過unowned定義無主引用
    1. 不會產生強引用,非可選類型间景,實例銷毀后仍然儲存著實例的內存地址(類似OC中的unsafe_unretained
    2. 試圖在實例銷毀后訪問無主引用订晌,會產生運行時錯誤(野指針)

weakunowned的使用限制
  • weak饿自、unowned只能用在類實例上面
protocol Livable: AnyObject { }
class Person { }

weak var p0: Person?
weak var p1: AnyObject?
weak var p2: Livable? //因為Livable協(xié)議遵守AnyObject汰翠,所以它只能被類遵守

unowned var p10: Person?
unowned var p11: AnyObject?
unowned var p12: Livable?

Autoreleasepool自動釋放池

在需要緩解內存壓力的地方,使用autoreleasepool

autoreleasepool {
    print("kkkk")
}

循環(huán)引用
  • weak昭雌、unowned都能解決循環(huán)引用的問題复唤,unowned要比weak少一些性能消耗
    1. 在生命周期中可能會變成nil的使用weak
    2. 初始化賦值之后再也不會變成nil的,建議使用unowned

閉包的循環(huán)引用
  • 閉包表達式默認會對用到的外層對象產生額外的強引用(對外層對象進行了retain操作)
  • 下面代碼會產生循環(huán)引用城豁,導致Person對象無法釋放(deinit無調用)
class Person {
    var fn: (() -> ())?
    func run() { print("Person run") }
    deinit { print("Person deinit") }
}
func test() {
    let p = Person()
    p.fn = { p.run() }
}
test()

通過匯編可以看到苟穆,進行了retain操作,導致計數(shù)器+1,最終release之后雳旅,計數(shù)器還是1跟磨,Person對象沒有釋放:


嘗試注釋掉p.fn = { p.run() }這行調用,再看下斷點匯編:這時候計算器已經是0了攒盈,Person對象被銷毀

因為閉包表達式用到了外面的對象抵拘,產生了強引用,導致無法釋放對象型豁。

  • 在閉包表達式的捕獲列表聲明weak或者unowned引用僵蛛,解決循環(huán)引用問題
func test() {
    let p = Person()
    p.fn = {
        [weak p] in
        p?.run()
    }
}
test()
p.fn = {
     [unowned p] in
     p.run()
}

甚至可以自定義名稱:

p.fn = {
      [weak wp = p, unowned up = p, a = 10 + 20] in
      wp?.run()
}
  • 如果想在定義閉包屬性的同時引用self,這個閉包必須是lazy的(因為在實例初始化完畢之后才能引用self
class Person {
    lazy var fn: (() -> ()) = {
        [weak self] in
        self?.run()
    }
    func run() { print("Person run") }
    deinit { print("Person deinit") }
}
func test() {
    var p = Person()
    p.fn()
}
test()
  • 如果lazy屬性是閉包調用的結果迎变,那么不用考慮循環(huán)引用問題(因為閉包調用后充尉,閉包的生命周期就結束了)
class Person {
    var age: Int = 0
    lazy var getAge: Int = {
        self.age
    }()
    deinit { print("Person deinit") }
}
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市衣形,隨后出現(xiàn)的幾起案子驼侠,更是在濱河造成了極大的恐慌,老刑警劉巖谆吴,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件倒源,死亡現(xiàn)場離奇詭異,居然都是意外死亡句狼,警方通過查閱死者的電腦和手機笋熬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來腻菇,“玉大人胳螟,你說我怎么就攤上這事〕锿拢” “怎么了旺隙?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長骏令。 經常有香客問我,道長垄提,這世上最難降的妖魔是什么榔袋? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮铡俐,結果婚禮上凰兑,老公的妹妹穿的比我還像新娘。我一直安慰自己审丘,他們只是感情好吏够,可當我...
    茶點故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般锅知。 火紅的嫁衣襯著肌膚如雪播急。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天售睹,我揣著相機與錄音桩警,去河邊找鬼。 笑死昌妹,一個胖子當著我的面吹牛捶枢,可吹牛的內容都是我干的。 我是一名探鬼主播飞崖,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼烂叔,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了固歪?” 一聲冷哼從身側響起蒜鸡,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎昼牛,沒想到半個月后术瓮,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡贰健,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年胞四,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片伶椿。...
    茶點故事閱讀 39,992評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡辜伟,死狀恐怖,靈堂內的尸體忽然破棺而出脊另,到底是詐尸還是另有隱情导狡,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布偎痛,位于F島的核電站旱捧,受9級特大地震影響,放射性物質發(fā)生泄漏踩麦。R本人自食惡果不足惜枚赡,卻給世界環(huán)境...
    茶點故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望谓谦。 院中可真熱鬧贫橙,春花似錦、人聲如沸反粥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至莫湘,卻和暖如春尤蒿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背逊脯。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工优质, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人军洼。 一個月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓巩螃,卻偏偏與公主長得像,于是被迫代替她去往敵國和親匕争。 傳聞我的和親對象是個殘疾皇子避乏,可洞房花燭夜當晚...
    茶點故事閱讀 44,947評論 2 355