對于iOS開發(fā)者來說,第一個要過的關(guān)大概就是iOS的內(nèi)存管理吧煤墙。
那么我第一篇就從iOS的內(nèi)存管理講起:
iOS內(nèi)存管理編程指南指出Objective-C提供了三種內(nèi)存管理方式:
1.Manual Retain-Relaease
開發(fā)者使用由NSObject和Runtime共同提供的引用計數(shù)模型麻惶,自己用代碼來管理內(nèi)存馍刮。
2.Automatic Reference Counting
ARC 自動引用計數(shù) 和MRR一樣同樣采用引用計數(shù),但是在編譯時插入內(nèi)存管理的方法窃蹋。這里ARC自動地幫助我們處理了引用計數(shù)相關(guān)的內(nèi)存操作卡啰。
3.Garbage Collection
垃圾回收。系統(tǒng)對于沒有引用的對象警没,自動化回收處理匈辱。Mac OS下使用,iOS不可以惠奸。
無論是內(nèi)存管理指南 還是 其他一些講到有關(guān)iOS內(nèi)存管理的書籍梅誓,都會提到內(nèi)存管理的方式:
1.自己生成的對象自己擁有(以alloc/new/copy/mutableCopy來頭的方法)
2.可以通過retain持有一個對象
3.不再需要一個對象時,要放棄對象的持有
4.使用中的對象不要進行release(引起crash)
ps:對于一些以alloc/new/copy/mutableCopy開頭的方法卻并不屬于上面所說的情況佛南,如:newer梗掰,copying,allocate等嗅回。對于一些能夠得到對象及穗,自己卻不持有的例子如[NSMutableArray array],其實是使用autorelease 實現(xiàn)的绵载。
autorelease的使用:
首先生成autopool 然后對象a調(diào)用autorelease把a對象放入autoPool中埂陆,autoPool調(diào)用drain相當于對pool內(nèi)所有的對象進行release
ps:autopool對象不可以使用autorelease方法。
ARC:
__strong 修飾符
所有的對象前綴都默認加上了__strong;
__strong 修飾的變量在超出它的作用域的時候會自動釋放娃豹,相當于調(diào)用了一次releease
就算是
因為是__strong強引用 也會變成自己持有焚虱。
ps:
__weak 修飾符
因為__strong會出現(xiàn)循環(huán)引用問題 所以引入了__weak修飾符
因為__weak修飾的變量持有對象的弱引用懂版,生成的對象會被立即釋放鹃栽。
_unsafe_unretained
使用_unsafe_unretained修飾的對象不屬于編譯器的內(nèi)存管理對象。
它和__weak修飾符一樣都不持有對象躯畴,所以生成的對象會被立即釋放民鼓。但是它和weak不同的是薇芝,在對象被釋放時weak修飾的指針變量會被設(shè)置成nil 而 _unsafe_unretained不會。
__autoreleasing 修飾符
在寫的時候我們很少會加上__autoreleasing修飾符
因為沒有指定修飾符夯到,所以默認是strong,因為return讓變量超出了作用域饮亏,所以該強引用的對象會被釋放耍贾,但是作為函數(shù)返回值編譯器會自動把它加入到autoreleasepool。
ps:訪問__weak修飾符的變量時克滴,必定會訪問注冊到autoreleasepool的對象逼争。__weak持有對象的弱引用优床,在訪問過程中劝赔,對象可能被廢棄。所以會把對象注冊到autoreleasepool中胆敞,保證在autoreleasepool結(jié)束之前都可以確保對象存在着帽。
ps: id *類型 默認修飾符是 __autoreleasing
ps:需要注意的是在ARC環(huán)境中要顯式轉(zhuǎn)換id和void *
這時可以使用__bridge?
__bridge有兩種__bridge_retained和__bridge_transfer
__bridge_retained 這種轉(zhuǎn)換讓a和p和b同時持有該對象
__bridge_transfer這種變換先讓p持有對象 釋放a 然后讓b持有對象釋放p
通常用來于CF之間的轉(zhuǎn)換。