1. 值類型(Value Types)
-
定義:每個實(shí)例持有獨(dú)立的數(shù)據(jù)副本,賦值或傳參時發(fā)生深拷貝。
- 典型類型:
Struct、Enum、基礎(chǔ)類型(Int、String、Array等)。
- 典型類型:
-
實(shí)現(xiàn)原理:
- 棧內(nèi)存分配:默認(rèn)在棧上分配(高效,無需GC)。
-
寫時復(fù)制(Copy-on-Write):Swift 對大型值類型(如
Array)優(yōu)化,僅在修改時復(fù)制數(shù)據(jù)。
-
優(yōu)點(diǎn):
- 線程安全:數(shù)據(jù)獨(dú)立,無需鎖。
- 無副作用:函數(shù)內(nèi)修改不影響外部變量。
- 確定性析構(gòu):離開作用域立即釋放。
-
缺點(diǎn):
- 大對象復(fù)制開銷:頻繁操作大型結(jié)構(gòu)體可能影響性能。
2. 引用類型(Reference Types)
-
定義:實(shí)例共享同一內(nèi)存地址,賦值或傳參時傳遞指針。
- 典型類型:
Class、Closure。
- 典型類型:
-
實(shí)現(xiàn)原理:
- 堆內(nèi)存分配:實(shí)例存儲在堆,通過引用計(jì)數(shù)(ARC)管理生命周期。
- 指針傳遞:變量存儲的是內(nèi)存地址。
-
優(yōu)點(diǎn):
- 高效共享:適合需要多對象共享同一狀態(tài)的場景。
- 繼承與多態(tài):支持面向?qū)ο筇匦浴?/li>
-
缺點(diǎn):
- 線程安全隱患:共享狀態(tài)需同步機(jī)制。
-
循環(huán)引用風(fēng)險:需用
weak或unowned打破強(qiáng)引用。
3. 如何選擇合適的類型?
-
選值類型當(dāng):
- 需要不可變性(如配置參數(shù))。
- 數(shù)據(jù)獨(dú)立性優(yōu)先(如坐標(biāo)點(diǎn)
CGPoint)。 - 避免副作用(函數(shù)式編程)。
-
選引用類型當(dāng):
- 需要共享狀態(tài)(如全局管理器
UserDefaults.standard)。 - 需要繼承或Objective-C互操作。
- 實(shí)例生命周期需精確控制(如UI組件)。
- 需要共享狀態(tài)(如全局管理器
4. 面試常見問題
-
值類型和引用類型在內(nèi)存管理上有何區(qū)別?
- 值類型棧分配,引用類型堆分配+ARC。
-
寫時復(fù)制(CoW)是如何實(shí)現(xiàn)的?
- 示例:
Array在修改時檢查引用計(jì)數(shù),若>1則復(fù)制底層存儲。
- 示例:
-
為什么Swift的String、Array采用結(jié)構(gòu)體而非類?
- 不可變性與性能優(yōu)化,避免不必要的共享。
-
如何避免引用類型的循環(huán)引用?
- 使用
weak或unowned修飾閉包或委托。
- 使用
-
以下代碼輸出什么?為什么?
struct S { var value: Int } class C { var value: Int = 0 } var a = S(value: 1) var b = a b.value = 2 print(a.value) // 1 let x = C() let y = x y.value = 2 print(x.value) // 2
5. 高級場景
- 值類型+協(xié)議:通過協(xié)議實(shí)現(xiàn)輕量級多態(tài)(無需繼承)。
-
混合使用:
class內(nèi)部封裝struct數(shù)據(jù)(如ViewModel持有Model結(jié)構(gòu)體)。
總結(jié)
-
默認(rèn)優(yōu)先選值類型:Swift標(biāo)準(zhǔn)庫大量使用結(jié)構(gòu)體(如
Int、Array),因其安全、高效。 - 必要時用引用類型:當(dāng)共享狀態(tài)或需要繼承時選擇類。