---
# System prepended metadata

title: ARC(自動參考計數機制)

---

# ARC(自動參考計數機制)

[TOC]

ARC: 將資源（例如物件、記憶體或磁盤空間等）被參考的次數保存起來。簡單來說，把參考儲存到記憶體中，並自動釋放沒有在使用的參考所佔用的記憶體。

Reference Counting 僅適用於類別 (class) 的實例 (instance)，而不適用於結構 (structures) 和枚舉 (enumerations)，因為他們兩個都是數值型別 (Value Type)，而不是參考型別 (Reference Type)。

![](https://i.imgur.com/mbYYQHM.png)


- 通常當一個屬性被建立時，除非 Reference 被設置為 <font color="red">weak</font> 或 <font color="red">unowned</font>，否則會預設為 strong。
- 當屬性被設為 <font color="red">weak</font> 時，Reference count 不會增加
- <font color="red">unowned</font> reference 剛好在兩者中間，既不是 strong，也不是可選擇型別。因為 Reference 是維持被分配的狀態，編譯器會假定物件未被釋放。

### 使用 weak 還是 unowned

- 用 weak 還是用 unowned ，和物件的 lifetime （生命週期）有關：
    - weak：兩個物件的生命週期完全和對方沒關係（其中一方什麼時候賦值為nil，對對方都沒影響）
    - unowned：其中一個物件銷毀，另一個物件也要跟著銷毀

## Reference Cycle
物件是由其他物件組成，當被參考的物件死亡時，記憶體實際上卻沒有釋放空間，造成記憶體洩漏(memory leak)。

## [closure](https://docs.swift.org/swift-book/LanguageGuide/Closures.html)
closure 會捕捉外部使用的變數，有可能造成 retain cycle

### capture list (閉包裡的 [] )
在閉包內，把捕抓(capture)到的物件、值，放到一個方括號中的語法。

在方括號(capture list)中，可以利用 weak 、 unowned 關鍵字來解決 closures 和類實例（class instance）之間的 Reference Cycle。

- Value Type
    - 使用 Capture List：會copy一份到closures裡面，是不能修改的let常量，和原來外面的值就沒關係
    - 非使用 Capture List：closures內外共享一個值

- Reference Type，無論是否使用 Capture List，指向的都是同一個Reference。Capture List 的作用，是用於宣告是weak，還是unowned型別的Reference。
    - closure 生命週期與對象生命周期一致時，使用 unowned

## 參考連結
- [Automatic Reference Counting](https://docs.swift.org/swift-book/LanguageGuide/AutomaticReferenceCounting.html)
- [記憶體管理：了解 Strong、Weak 和 Unowned Reference 輕鬆解決記憶體洩漏](https://www.appcoda.com.tw/memory-management-swift/)
- [Swift基礎 — ARC 記憶體管理Weak 、Unowned](https://medium.com/one-two-swift/arc-%E8%A8%98%E6%86%B6%E9%AB%94%E7%AE%A1%E7%90%86-weak-unowned-b3f5ae4239c7)
- [Unowned 还是 Weak？生命周期和性能对比](https://swift.gg/2017/05/16/unowned-or-weak-lifetime-and-performance/)
- [Swift 中的weak，unowned，Closure Capture List](https://www.jishuwen.com/d/202n/zh-tw)
- [weak self podcast](https://weakself.dev/episodes/10)