一 內存管理
一 什么是內存管理?
就是確保開辟的“堆空間”被正確的釋放。
二 為什么要內存管理?
1.移動設備的內存都是極其有限的,每個app所占用的內存是非常有限的。
2.當app所占的內存較多的時候,系統會發出警告,必須要銷毀掉一些不使用的空間,但如 果系統回收掉之后,還是占用太多,app就會閃退的情況。
3.管理范圍:任何繼承了NSObject的對象,而對于其他的基礎數據類型(int,char。。結 構體,1枚舉)無效,因為這些東西都是系統自動回收,本質原因是因為這些基礎數據類型 存放的空間跟“對象”不一樣。
三 OC中的內存管理的方式: //輸入gar進行切換
1.手動內存管理(MRC)
2.自動內存管理(ARC)Automatic Reference Counting
四 為什么要學習手動內存管理
1.要理解自動內存管理,必須以手動內存管理為基礎;
2.使用ARC,可能會因為代碼的不規范,導致內存各種問題。。
3.導入的第三方庫,或者一些舊文件,這些代碼都不支持ARC。。
4.一些公司崇拜MRC;
5.面試;
五 學習內存管理會遇到以下問題:
內存泄露:如果堆空間沒有被釋放;
重復釋放:同一個空間被釋放多次;
提前釋放:釋放了還需要使用的空間;
六 引用計數器的概念
1.為了解決以上問題,OC引用了“引用計數器”的概念
1)每個對象一創建出來,就默認有一個“引用計數器”的屬性,是一個整數,表 示“該對象被引用的次數”,即有多少人正在使用這個對象;
2)每個OC對象的內部專門有4個字節的存儲空間來存儲引用計數器的值;
2.引用計數器的操作
1)當我們使用alloc,new,或者copy創建一個新對象的時候,新對象的引用計數器 的值“ +1 ”;
2)當我們給對象發送retain消息的時候,可以使得該對象的引用計數器的值 +1 ;
3)當給對象發送一條release消息的時候,可以使得改對象的引用計數器的值 -1;
4)當一個對象的引用計數器的值為0的時候,代表著該對象沒有人使用了,對象的內 存就會被系統回收,這個時候系統的內部會自動的調用dealloc方法來回收內 存;
Person *p1 = [[Person alloc] init];//1
Person *p2 = [p1 retain];//2 //用新指針指向原來的指針時,原來指針 調用retain方法;
Person *p3 = [p1 retain];//3
[p3 release];//2
[p2 release];//1
[p1 release];//0
總結:
1.retain:引用計數器的值+1;
2.release:引用計數器的值-1;
3.retaincount:獲得當前對象的引用計數器的值;
4.對象銷毀:
1)當一個對象的引用計數器的值為0時,那么它將被銷毀;
2)當一個對象被銷毀的時候,系統的內部會自動的調用dealloc方法, 3)一般重寫dealloc方法,在這個方法里面釋放相關資源,就好比對象的遺言;
4)一旦重寫了dealloc方法,就在MRC下,就必須調用[super dealloc],且放在最 后調用;在ARC下,不需要調用;
5)不要直接接受調用dealloc方法;
6)一旦對象被回收,它就成為了僵尸對象,堅持使用對象程序會發生崩潰;
內存管理的黃金法則:
1.凡是使用alloc,new,copy(mutablecopy),retain的時候,引用計數器的值+1, 那么必須使用release或者autorelease方法,當使用release,引用計數器的值-1,當引用 計數器的值為0,這個對象才會被銷毀;
2.誰創建誰release(誰寫的alloc,誰release);
二 多個對象的內存管理
Person(擁有一輛汽車)
Car
【Demo】-【2-多個對象的內存管理】
三 不可變字符串的內存管理
用copy修飾字符串,是為了防止外界隨意更改相關內容;
不管是可變字符串還是不可變字符串,始終堅持內存管理的黃金法則來管理內存就不會出錯;
四 數組的內存管理
遵守黃金法則
見【Demo】-【5-數組的內存管理】
五 copy和MutableCopy的區別 用于字符串、數組、字典
copy:不管對象之前是可變的還是不可變的,那么copy之后,返回的新對象一定是不可變 的;
MutableCopy:不管對象之前是可變的還是不可變的,那么MutableCopy之后,返回的 新對象一定是可變的;
見【Demo】-【6-copy和mutableCopy】
六 自動釋放池
自動釋放池就是為了幫我們把對象達到一個延遲銷毀的目的;
什么是自動釋放池?
自動釋放池就好比一個容器,當給某個對象發送autorelease消息的時候,就會將這個對象 加入到離它最近的自動釋放池中,當池子銷毀的時候,系統內部會自動的對該池子中所有的 對象執行release一次,這樣就可以達到延遲銷毀的目的;
見【Demo】-【7-自動釋放池】
【問】autorelease是讓對象的引用計數器-1碼?
【答】不是,autorelease只是把對象加入了自動釋放池中,只有當池子銷毀的時候,系統 才會自動的對池子中所有的對象發送一次release消息;
總結:
1.對象的成員變量(OC對象)在init構造方法中創建,應該dealloc方法中release;
2.對象的屬性使用retain,copy修飾的,那么,應該在dealloc方法中release;
3.字符串表面上不遵守內存管理原則,但我們依然要用黃金法則來管理,即每一個+對應一 個-;
內存管理的黃金法則:
1)凡是使用alloc,new,copy(mutablecopy),retain的時候,引用計數器的值 +1, 那么必須使用release或者autorelease方法,當使用release,引用計數器的值-1, 當引用計數器的值為0,這個對象才會被銷毀;
2)誰創建誰release(誰寫的alloc,誰release);
4.單例對象是個例外,不用釋放,因為整個工程隨時都有可能要用到單例對象,隨著工程退 出,而銷毀!
5.release和autorelease的區別;
6.copy和mutableCopy的區別;