隨着移動設備的內存愈來愈大,程序員也已經度過了爲了那一兩M的內存在系統的抽絲剝繭的年代,對於JAVA的開發者,對內存更是伸手即取,而且從不關心何時還回去。可是,程序的掌控度對程序員來講是相當重要的,任何語言的內存管理機制的初衷也是在有限的空間裏完成最精緻的邏輯。程序員
ARC是xcode5中引入的自動引用計數,其原理與MRC是同樣,只是系統幫助咱們添加了retain和release。如今在xcode中新建的項目默認都是ARC的環境,咱們能夠經過設置其爲MRC。xcode
在BuildSettings中搜索ARC:安全
將下面的參數設置爲NO,默認是YES。app
這時項目工程的環境就變成了MRC。學習
現實中的許多舊的項目,還有一些比較老的第三方庫,可能都是採用MRC環境編寫的,咱們在對其進行擴展或者作新項目的兼容的時候,能夠在xcode中對其進行混編。ui
選擇:target->build phases->compile sourcesspa
若是工程是ARC,要混編MRC的文件,咱們選中compiler flags,後面設置爲-fno-objc-arc指針
若是工程是MRC,要混編ARC文件,咱們在後面設置-fobjc-arccode
不管你是隻注重於代碼邏輯,將內存交給ARC的新時代程序員,仍是依然對apple的信任不足,依然事必躬親的MRC古板程序員,我想你都應該瞭解IOS中內存管理的機制,儘管ARC機制很成熟也很可靠,但是依然會有不少應用存在循環應用,內存泄露等問題,要知道,ARC不是萬能的,它僅僅只是幫你省去寫一些繁瑣的代碼。對象
首先,在Object-C中建立對象返回的並非對象自己,而是一個指針。好比咱們使用alloc申請空間,會常常這樣作:
UIImage * image = [[UIImage alloc]init];
這裏,調用的alloc時,系統將給咱們建立的類分配一塊內存空間,並返回一個指向這個空間的指針。調用init時對對象進行初始化。若是此時,咱們將image這個指針置爲nil:image=nil;那樣將形成內存泄露,系統分配給image的空間永遠沒法回收。因此,在咱們不須要image這個對象時,咱們會使用dealloc方法將其交還給系統:[image dealloc];然而這裏,有將產生一個嚴重的問題,若是咱們此時打印image的指針,會發現它如今成了一個危險東西,由於它指向的東西不存在了,而它卻依然指向那個地方,這即是不少程序員的噩夢:野指針。爲此,咱們應該養成一個好習慣,不用的指針置爲nil,全部對空指針進行的操做都被認爲是安全的。
經過上面的理解,咱們發現了一個很是麻煩的地方,我申請了一塊內存空間,若是我將指針置空了而沒有釋放對象,則會內存泄露,若是我提早釋放了對象,又極可能會有野指針的出現。而且若是有不少類都引用了這個對象,我甚至的不知道我應該何時釋放它。所以,Object-C爲咱們引入了引用計數這種管理內存的方法,任何引用這個對象的地方,都應該讓這個對象的引用計數加1。一樣,任何再也不須要這個對象的地方,也應該使它的引用計數減1,如此一來,對象內存便被統一的管理了起來。
引用計數內存管理的機制是對象的計數,每一個對象至少會有一個引用者,若是沒有了引用者,對象會被釋放。
黃金法則:
一、當你使用alloc,new,copy,mutableCopy建立對象時,你才須要管理他們。
二、你可使用retain給一個對象增長引用計數。
三、當你再也不須要一個對象時,你必須調用release減小其引用計數。
四、你不能釋放不屬於你的對象的全部權。
上面就是黃金法則的全部內容,我譯的可能不到位,總結爲一點,也是相當重要的一點就是:誰建立了對象,誰釋放掉對象。誰增長了引用計數,誰就在不用時減小計數。alloc,new,copy,mutableCopy,retain這些方法會使引用計數增長,release會使引用計數減小,當計數爲0時,系統會調用dealloc釋放內存。
爲了方便內存管理,避免咱們頻繁的調用release方法,Object-C中還爲咱們引用了一種機制:自動釋放池。自動釋放池的原理其實只是延時釋放,它並無幫咱們作太多的工做。自動釋放池的使用方式有兩種:
一、MRC時:
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc]init];//建立一個自動釋放池,系統默認會爲咱們建立一個,咱們也能夠建立本身的。 UIImage * image = [[[UIImage alloc]init] autorelease];//在池內建立一些對象,會和最近的自動釋放池匹配 [pool release];//這時自動釋放池會向池子中的每個對象發送release消息
二、ARC時:
@autoreleasepool { UIImage * image = [[[UIImage alloc]init] autorelease]; }
疏漏之處 歡迎指正
學習使用 歡迎轉載
專一技術,熱愛生活,交流技術,也作朋友。
——琿少 QQ羣:203317592