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...