day9---內存管理

一 內存管理

一 什么是內存管理?
就是確保開辟的“堆空間”被正確的釋放。

二 為什么要內存管理?
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的區別;
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 內存管理 簡述OC中內存管理機制。與retain配對使用的方法是dealloc還是release,為什么?需要與a...
    丶逐漸閱讀 2,013評論 1 16
  • 29.理解引用計數 Objective-C語言使用引用計數來管理內存,也就是說,每個對象都有個可以遞增或遞減的計數...
    Code_Ninja閱讀 1,541評論 1 3
  • iOS內存管理 概述 什么是內存管理 應用程序內存管理是在程序運行時分配內存(比如創建一個對象,會增加內存占用)與...
    蚊香醬閱讀 5,762評論 8 119
  • 內存管理是程序在運行時分配內存、使用內存,并在程序完成時釋放內存的過程。在Objective-C中,也被看作是在眾...
    蹲瓜閱讀 3,198評論 1 8
  • 11.看下面的程序,第一個NSLog會輸出什么?這時str的retainCount是多少?第二個和第三個呢? 為什...
    AlanGe閱讀 757評論 1 4