OC 屬性修飾符底層原理(面試高頻版)
OC 屬性修飾符的底層邏輯,核心圍繞 引用計(jì)數(shù)管理 和 內(nèi)存拷貝機(jī)制 展開(kāi),面試官最愛(ài)追問(wèn)原理差異和使用場(chǎng)景,以下是分點(diǎn)拆解:
1. strong
底層原理
? 本質(zhì)是強(qiáng)引用,依賴 Runtime 的 objc_setProperty 函數(shù)實(shí)現(xiàn)。
? 賦值時(shí)執(zhí)行三步操作:
1. 對(duì)新值調(diào)用 objc_retain,使其引用計(jì)數(shù) +1,確保對(duì)象不被釋放;
2. 對(duì)舊值調(diào)用 objc_release,使其引用計(jì)數(shù) -1,若計(jì)數(shù)歸零則銷毀對(duì)象;
3. 將屬性指針指向新值的內(nèi)存地址。
? 內(nèi)存管理:在 ARC 下自動(dòng)完成 retain/release,MRC 下需手動(dòng)管理。
面試關(guān)鍵點(diǎn)
? 是 OC 對(duì)象屬性的默認(rèn)修飾符,用于持有對(duì)象;
? 風(fēng)險(xiǎn)點(diǎn):容易引發(fā)循環(huán)引用(如 self 強(qiáng)引用 block,block 又強(qiáng)引用 self),需配合 weak 解決。
2. copy
底層原理
? 核心是創(chuàng)建對(duì)象副本,依賴對(duì)象必須遵循 NSCopying 協(xié)議并實(shí)現(xiàn) copyWithZone: 方法。
? 賦值時(shí)流程:
1. 調(diào)用新值的 copyWithZone: 方法生成副本;
2. 對(duì)副本執(zhí)行 strong 的 retain/release 邏輯(持有副本,釋放舊值);
3. 屬性指針指向副本的內(nèi)存地址。
? 拷貝類型分兩種(面試必問(wèn)):
淺拷貝:源頭是不可變對(duì)象(如 NSString),copyWithZone: 直接返回原對(duì)象,僅引用計(jì)數(shù) +1,共享內(nèi)存(性能高);
深拷貝:源頭是可變對(duì)象(如 NSMutableString),copyWithZone: 會(huì)開(kāi)辟新內(nèi)存,生成一個(gè)不可變的新對(duì)象,與原對(duì)象獨(dú)立。
面試關(guān)鍵點(diǎn)
? 只能修飾不可變對(duì)象屬性(如 NSString),修飾可變對(duì)象(如 NSMutableString)會(huì)導(dǎo)致調(diào)用可變方法崩潰;
? 核心作用:防止外部可變對(duì)象篡改屬性值,保證屬性的不可變性。
3. weak
底層原理
? 本質(zhì)是弱引用,不參與引用計(jì)數(shù)管理,底層依賴 Runtime 的 SideTable(哈希表) 實(shí)現(xiàn)。
? 賦值時(shí):直接將指針指向?qū)ο蟮刂?,不調(diào)用 retain,引用計(jì)數(shù)不變化;
? 對(duì)象銷毀時(shí):Runtime 會(huì)遍歷 SideTable 中所有指向該對(duì)象的 weak 指針,自動(dòng)將其置為 nil,從根源避免野指針。
面試關(guān)鍵點(diǎn)
? 專門(mén)解決循環(huán)引用(如代理模式、block 中引用 self);
? 特點(diǎn):weak 指針不會(huì)持有對(duì)象,對(duì)象銷毀后自動(dòng)置 nil,是安全的非持有引用。
4. assign
底層原理
? 本質(zhì)是直接賦值,底層就是簡(jiǎn)單的內(nèi)存拷貝(類似 C 語(yǔ)言的 = 賦值)。
? 對(duì)于基本數(shù)據(jù)類型(int/float 等):直接拷貝棧上的數(shù)值,無(wú)需內(nèi)存管理;
? 對(duì)于 OC 對(duì)象:直接拷貝對(duì)象的指針地址,但不調(diào)用 retain/release,不管理引用計(jì)數(shù)。
面試關(guān)鍵點(diǎn)
? 僅適用于基本數(shù)據(jù)類型;
? 修飾 OC 對(duì)象時(shí),對(duì)象銷毀后指針不會(huì)置 nil,會(huì)變成野指針,訪問(wèn)時(shí)觸發(fā)崩潰,面試中??肌盀槭裁?assign 不能修飾對(duì)象”。
面試高頻追問(wèn)應(yīng)答模板
1. strong 和 copy 的區(qū)別?
→ strong 是持有原對(duì)象,多個(gè) strong 指針共享同一內(nèi)存;copy 是生成副本(分深淺拷貝),屬性與原對(duì)象獨(dú)立,且 copy 能保證屬性不可變。
2. weak 為什么能自動(dòng)置 nil?
→ 底層依賴 Runtime 的 SideTable 哈希表,對(duì)象銷毀時(shí) Runtime 會(huì)自動(dòng)遍歷并清空所有指向它的 weak 指針。
3. 什么時(shí)候用 copy?
→ 當(dāng)屬性是不可變類型(如 NSString),且賦值源頭可能是可變對(duì)象時(shí),用 copy 防止外部篡改