Objective C中記憶體管理

2021-09-21 16:22:32 字數 2955 閱讀 8864

ios記憶體管理簡介

ios記憶體使用原則:

1.  物件的所有權與銷毀

①誰建立,誰釋放:如果是以alloc,new或者copy建立的物件,則必須呼叫release或者autorelease方法釋放記憶體,如果沒有釋放,則導致記憶體洩漏。除了alloc,new,或copy之外的方法建立的物件都被宣告了autorelease。

②誰retain,誰釋放:如果對乙個物件傳送retain訊息,其引用計數會+1,則使用完必須傳送release或autorelease方法釋放記憶體或恢復引用計數,如果沒有釋放,同樣導致記憶體洩漏。

③沒建立且沒retain,別釋放:不要釋放那些不是自己alloc或者retain的物件,否則程式會crash,不要釋放autorelease的物件,否則程式會crash。

2.   物件的深拷貝與淺拷貝

①深拷貝:複製指標所引用的資料,並將其賦給副本的例項變數。其流程是先建立乙個

新的物件且引用計數為1,並用就舊物件的值初始化這個新物件。

classa *obja=[[classa alloc] init];

classa *objb=[obja copy];

objb是乙個新物件,引用計數為1,且objb的資料等同於obja的資料。

注:objb需要釋放,否則會記憶體洩漏

②淺拷貝:將原始物件的指標複製到副本中,原始物件和副本共享引用資料。其流程是,無需引入新的物件,把原有物件的引用計數+1即可。

classa *obja=[[classa alloc] init];

classa *objb=[obja retain];

注:objb需要釋放,恢復obja的引用計數,否則會引起記憶體洩漏。

3.  物件的訪問方法

①屬性的宣告與實現

變數宣告的常用屬性型別包括:

readonly屬性:只能讀,不能寫;

assign屬性:是預設屬性,直接賦值,沒有任何保留與釋放問題;

retain屬性:會增加原有物件的引用計數,並且在賦值前會釋放原有物件,然後再進行賦值。

copy屬性:會複製原有物件,並在賦值前釋放原有物件,然後再進行賦值。

②屬性宣告可能帶來的問題:

當乙個非指標變數使用retain(或者copy)這個屬性時,盡量不要顯性的release這個變數,直接給這個變數置空即可,否則容易產生過度釋放,導致程式crash。

ios中autorelease機制

1.一般地,在新建乙個iphone專案的時候,xcode會自動在mian函式中為你建立乙個autorelease pool,其全名是nsautoreleasepool,是objective-c中的乙個類。

2.在nsautoreleasepool中包含了乙個可變陣列,用來儲存被宣告為autorelease的所有物件,如果乙個物件被宣告為autorelease,系統所做的工作就是把這個物件加入到這個陣列中去。

3.當autoreleasepool自身被銷毀的時候,它會遍歷這個陣列,release陣列中的每乙個成員,如果此時陣列中成員的retain count為1,那麼release之後,retain count為0,物件正式被銷毀。如果此時陣列中成員的retain count大於1,那麼release之後,retain count大於0,此物件依然沒有被銷毀,記憶體洩漏。

main函式如下:

int main(int argc,char *ar**)

4.自動釋放池所涉及到的一些常見問題

在ios程式開發的時候,會經常遇到在滑動列表,頻繁訪問,頻繁開啟或關閉資料庫的時候,記憶體會莫名其妙的增長,其實,這些都很有可能是autorelease機制的所導致的。

分析如下:

①滑動列表的時候,記憶體增長原因:沒有使用uitableview的reuse機制,導致每顯示乙個cell都用autorelease的方式重新alloc一次,導致cell的記憶體不斷增加。或者,每個cell會顯示乙個單獨的uiview,在uiview發生記憶體洩漏,導致cell記憶體不斷增長。

②頻繁訪問的時候,記憶體增長原因:頻繁的訪問網路,導致ios內部api,會不斷的分配autorelease方式的buffer來處理的解碼與顯示。

③頻繁開啟和關閉sqlite資料庫,記憶體增長原因:在進行sqlite頻繁開啟和關閉操作,而且讀取的資料buffer較大,那麼sqlite在每次開啟關閉的時候,都會利用autorelease的方式分配51k的記憶體,如果訪問次數多,記憶體馬上會頂到幾十兆,甚至上百兆,所以,對於頻繁讀寫資料庫且資料buffer較大的情況,可以設定sqlite長連線方式,避免頻繁開啟或關閉資料庫。

ios記憶體使用誤區

.2.迴圈引用:迴圈引用,容易產生野引用,記憶體無法**,最終導致記憶體洩漏。可以通過弱引用的方式打破迴圈引用鏈。所謂的弱引用就是不需要retain,直接採取賦值的方式,這樣的話可以避免迴圈引用,同時也要注意避免重複釋放的問題。

ios記憶體警報處理流程

1. 

2. 

4. 

ios記憶體檢查工具

1.   編譯分析工具analyze

可以發現編譯中的warning,記憶體洩漏隱患,甚至是邏輯上的問題,從而避免嚴重的由於記憶體引起的嚴重的bug。

2.   記憶體檢測工具

①記憶體洩漏檢測工具——leak

②記憶體猛增檢測工具——allocations

二者的詳細使用,可以自己查閱相關資訊進行了解。

總之,對於ios中記憶體的管理,需要我們在實際的程式開發中通過編寫相應**,以及除錯相關由記憶體引起的的問題,才可以得到比較好的體會。如果在開發過程中,不能按照分配原則進行記憶體的合理分配與釋放,將會對整個應用程式的效能造成很嚴重的影響,甚至導致其崩潰。所以開發者必須在深刻理解ios記憶體管理機制的基礎上,採用最佳的記憶體管理方式,才能獲得優良的使用者體驗。

Objective C記憶體管理

objective c的物件記憶體管理是一件非常有意思的事情,由其是在iphone嵌入式裝置中 想玩的省心點,就得熟知它的管理規則,由其是記憶體的管理機制。了解它的品性了才能在cocoa的世界裡如魚得水。否則,反之 如水得魚!1,乙個物件可以有乙個或多個擁有者 2,當它乙個擁有者都沒有時,它就會被 ...

Objective C 記憶體管理

objective c 記憶體管理 nsautoreleasepool pool nsautoreleasepool alloc init pool drain 事實上程式中可以有多個自動釋放池。自動釋放池其實並不包含實際的物件本身,僅僅是對釋放的對 象的引用。通過向目前的自動釋放池傳送一條auto...

Objective C 記憶體管理

objective c中,記憶體物件分二類 1 值型別,如 int float struct等基本資料型別 2 引用型別,通常是指繼承自nsobject類的oc物件 值型別在棧中,由系統自動管理,而引用型別在堆上,需要我們自己手工進行管理 oc中提供了二種記憶體管理機制 1 手動引用計數 mrc m...