收錄:空杯子
前面的話
屬性關(guān)鍵字是iOS開發(fā)中的基礎脚翘。 基礎往往容易被忽略喜最,但是細節(jié)決定成敗艺挪。 如果面試時,忽然來一發(fā)屬性關(guān)鍵字相關(guān)的問題诉濒,回答的不好汗唱,那給面試官的印象就會差很多屡拨,成為了木桶短板的一個攻冷〈逼茫可能前面回答的好建立的優(yōu)勢就沒了。
開始面試
我正在會議室略有緊張的等待面試讲衫,忽然看到一個穿著格子襯衫,大腹便便的中年男子拿著簡歷向我走來孵班, 我看著他頭上快要絕頂?shù)念^發(fā)涉兽,心想這肯定是個iOS開發(fā)技術(shù)牛逼閃閃的老前輩。
還好看過《iOS之一起進大廠》系列篙程,我的知識很淵博枷畏,基礎很牢固,不慌虱饿。剛緊張到提到嗓子眼的心拥诡,又按下去了触趴。淡定從容,一點都不虛好伐渴肉,就是這么自信淡定冗懦。
我什么時候也能變成那樣厲害的高手
面試官:
小伙子,看你簡歷 仇祭,你對開發(fā)基礎了解的很透徹啊披蕉,那咱們今天就聊聊屬性關(guān)鍵字把。 你對屬性關(guān)鍵字怎么理解乌奇?
屬性關(guān)鍵字可以分為三種類型:
- 讀寫權(quán)限的類型: readonly ,readwrite
- 原子類 : atomic 没讲,nonatomic
- 引用計數(shù) : retain/strong/copy,assign/unsafe_unretained礁苗,weak
讀寫權(quán)限的類型: readonly ,readwrite
- readwrite 是可讀可寫特性爬凑;會自動生成getter方法和setter方法
- readonly 是只讀特性 只會生成getter方法 ,不會生成setter方法
原子類: atomic nonatomic
atomic是保證賦值和獲取是線程安全的试伙。 這里說的是對成員屬性的直接賦值和獲取嘁信,并代表操作和訪問。 對于atomic的屬性迁霎,系統(tǒng)生成的 getter/setter 會保證 get吱抚、set 操作的完整性,不受其他線程影響考廉。
retain關(guān)鍵字
只有在MRC的環(huán)境下使用秘豹。 retain引起對象的引用計數(shù)加1, release引起引用計數(shù)減1,當引用計數(shù)為0時昌粤,dealloc函數(shù)被調(diào)用既绕,內(nèi)存被回收。
那你說說strong和weak的區(qū)別是涮坐?
strong 表示指向并擁有該對象凄贩。其修飾的對象引用計數(shù)會加1.該對象只要引用計數(shù)不為0則不會被銷毀。當然強制將其置為nil也可以銷毀它袱讹。 weak 表示指向但不擁有該對象疲扎。其修飾的對象引用計數(shù)不會增加。無需手動設置捷雕,該對象會自行在內(nèi)存中銷毀椒丧。
如何理解的atomic的線程安全呢,有沒有什么隱患救巷?
atomic對一個數(shù)組壶熏,進行賦值或獲取,是可以保證線程安全的浦译。但是如果進行數(shù)組進行操作棒假,比如給數(shù)據(jù)加對象或移除對象溯职,是不在atomic的保證范圍。
strong 和weak的區(qū)別帽哑?
strong 表示指向并擁有該對象谜酒。其修飾的對象引用計數(shù)會加1.該對象只要引用計數(shù)不為0則不會被銷毀。當然強制將其置為nil也可以銷毀它祝拯。 weak 表示指向但不擁有該對象甚带。其修飾的對象引用計數(shù)不會增加。無需手動設置佳头,該對象會自行在內(nèi)存中銷毀鹰贵。
assign 和weak的區(qū)別有哪些?
assign修飾基礎數(shù)據(jù)類型康嘉,int, BOOL
assign修飾對象類型碉输,不改變對象的引用計數(shù)。
assign 會產(chǎn)生懸垂指針亭珍, assign 的對象被釋放之后敷钾,對象指針還是會指向原來的地址,會產(chǎn)生懸垂指針 ,導致程序內(nèi)存泄露和程序崩潰肄梨。
weak不改變修飾對象的引用計數(shù)
所指向的對象在被釋放后自動設置為 nil.
他們的區(qū)別:
1阻荒、assign可以修飾對象和基本數(shù)據(jù)類型, weak只修飾對象
2、assign 所修飾的對象被釋放后众羡,還會指向原對象內(nèi)存地址侨赡。weak 所修飾的對象被廢棄之后,weak 所修飾對象會被設置為nil粱侣。
但是他們有一個共同點羊壹,他們都不會改變修飾對象的引用計數(shù)。
copy關(guān)鍵字影響了對象的可變和不可變屬性嗎齐婴?
可變對象(mutable)copy和mutableCopy都是深拷貝 不可變對象(immutable)的copy是淺拷貝,mutableCopy是深拷貝 copy方法返回的都是不可變對象,若被拷貝對象是可變對象,返回的也是不可變對象油猫。 例子解析如下:
淺拷貝和深拷貝的區(qū)別?
淺拷貝只是對 內(nèi)存地址的復制柠偶,兩個指針指向同一個地址情妖,增加被拷貝對象的引用計數(shù),沒有發(fā)生新的內(nèi)存分配诱担。
深拷貝:目標對象指針和源對象指針鲫售,指向兩片內(nèi)容相同的內(nèi)存空間。
2個特點:不會增加被拷貝對象的引用計數(shù)该肴,產(chǎn)生了新內(nèi)存分配,出現(xiàn)了2塊內(nèi)存藐不。
總結(jié)區(qū)別:
淺拷貝增加引用計數(shù)匀哄,不產(chǎn)生新的內(nèi)存秦效。
深拷貝不增加引用結(jié)束,會新分配內(nèi)存
NSMutableArray用copy修飾會出現(xiàn)什么問題?
出現(xiàn)調(diào)用可變方法不可控問題涎嚼,會導致程序崩潰阱州。 具體原因如下:
給Mutable 被聲明為copy修飾的屬性賦值, 過程描述如下:
1.如果賦值過來的是NSMutableArray對象,會對可變對象進行copy操作,拷貝結(jié)果是不可變的,那么copy后就是NSArray
2.如果賦值過來的是NSArray對象, 會對不可變對象進行copy操作,拷貝結(jié)果仍是不可變的,那么copy之后仍是NSArray法梯。
所以不論賦值過來的是什么對象,只要對NSMutableArray進行copy操作,返回的對象都是不可變的苔货。
那原來屬性聲明的是NSMutableArray,可能會調(diào)用了add或者remove方法,拷貝后的結(jié)果是不可變對象,所以一旦調(diào)用這些方法就會程序崩潰(crash)
MRC下如何重寫retain修飾變量的setter方法立哑?
這里關(guān)鍵點在于夜惭,如果恰好設置的是原來的對象铛绰,不做判斷的話敢会,就會導致把自己對象給釋放了,會導致程序訪問異常姐帚。所以需要先做判斷吏垮。
weak屬性修飾的變量,如何實現(xiàn)在變量沒有強引用后自動置為 nil 惫皱?
runtime 維護了一個weak_table_t 弱引用表 ,用于存儲指向某一個對象的所有weak指針。weak表其實是一個哈希表尤莺,
key是所指對象的地址旅敷,value是weak指針的地址的數(shù)組颤霎。
在對象回收的時候媳谁,根據(jù)對象的地址將所有weak指針地址的數(shù)組友酱,遍歷數(shù)組把其中的數(shù)據(jù)置為nil
__weak 和 _Unsafe_Unretain 的區(qū)別系羞?
weak 修飾的指針變量庐杨,在指向的內(nèi)存地址銷毀后各吨,會在 Runtime 的機制下,自動置為 nil树绩。
_Unsafe_Unretain不會置為 nil,容易出現(xiàn) 懸垂指針登下,發(fā)生崩潰篓冲。但是 _Unsafe_Unretain 比 __weak 效率高诽俯。
堅持看到這里的同學仙粱,你們個個都是人才硬霍,我好喜歡。