來談談記憶體管理
首先知道記憶體管理是什麼
應用程式記憶體管理是在程式執行的時候合理的分配記憶體(分配記憶體時不會造成記憶體洩露等)與清除記憶體(銷毀乙個不用的程式,減少記憶體使用)
在oc中有兩個管理記憶體的模式
mrr(manual retain-release),也被人稱作mrc(manual reference counting,手動引用計數)
arc(automatic reference counting,自動引用計數)
如何調整
在build setting中的objective-c automatic reference counting設定為yes即為arc
注意點,所有繼承nsobject的物件都需要管理記憶體,因為存放在堆裡面,基本資料型別不需要管理記憶體,因為放在棧裡面
堆: 一般由程式設計師分配釋放記憶體,若程式設計師不釋放,程式結束時可能由os釋放,其操作方式類似於資料結構中的鍊錶
棧: 由作業系統自動分配釋放,存放函式的引數值,區域性變數值等,其操作方式類似於資料結構中的棧(先進後出)
在ios5以前,程式都需要手動新增retain,release,atorelease來管理物件的記憶體
當使用alloc、new、copy、mutablecopy建立乙個新物件時,該新物件的引用計數器為1
當給物件傳送一條retain訊息時,物件的引用計數器+1(方法返回物件本身)
當給物件傳送一條release訊息時物件的引用計數器-1(方法無返回值)
當給物件傳送一條retaincount訊息時,返回物件的當前引用計數器(不要以該資料來判斷物件是否被釋放)
注意點:
對物件傳送乙個release訊息,不代表物件會釋放,只有物件的引用計數器為0時才會被釋放
在記憶體管理中,會產生將是物件,野指標,空指標
殭屍物件: 所占用的記憶體已經被**的物件,殭屍物件不能再使用
野指標: 指向殭屍物件的指標,給野指標傳送訊息會報錯exc_bad_access錯誤:訪問了一塊已經被**的記憶體
空指標: 沒有指向任何物件的指標(儲存的東西是nil,null,0),給空指標傳送訊息不會報錯,系統什麼也不會做,所以在物件被釋放時將指標設定為nil可以避免野指標錯誤
殭屍物件,xcode是不會主動監聽的,需要我們自己去開啟
步驟很簡單,
物件步驟為: edit scheme ->; run ->; diagnostics ->; objective-c的enable zombie objects打鉤
dog *d = [[dog alloc] init]; // 引用計數器 = 1
[d release]; // 引用計數器 - 1 = 0,指標所指向的物件的記憶體被釋放
[p release]; // 這句給野指標傳送訊息,會報野指標錯誤,開啟監聽殭屍物件會給出錯誤資訊**- -[person release]: message sent to deallocated instance 0x100206fd0
自動釋放池的概括
自動釋放池提供了延遲放棄乙個物件的所有權的機制,比如想要在乙個方法中返回乙個物件,如果先使用release放棄了該物件的所有權,那麼return返回的物件便是乙個殭屍物件,如果先進行return返回,那麼便無法放棄該物件的所有權,導致了記憶體洩漏
autorelease是一種支援引用計數的記憶體管理方式,只要在自動釋放池中給物件傳送一條autorelease訊息,就會將物件放到自動釋放池中,當自動釋放池被銷毀時,會對池中的所有物件傳送一條release訊息
autorelease方法會返回物件本身
autorelease方法不會修改物件的引用計數器
autorelease方法可以讓開發者不用實時關心什麼時候傳送release訊息
類工廠方法記憶體管理
在開發中,我們經常使用foundation框架中的類,在呼叫其類工廠方法建立乙個物件時,因為並不是使用alloc,new,copy或者mutablecopy方法建立的,所以並不需要我們自己在給該物件傳送release或者autorelease訊息,這是因為類工廠方法內部都已經在返回物件前進行過延遲釋放
我們在自己書寫類工廠方法時,也應該與系統處理方式相同,快速返回乙個autorelease物件的方式具體如下
+ (instancetype)person
快速返回乙個帶有引數的autorelease物件的方式具體如下
+ (instancetype)personwithname:(nsstring *)name
arc的概括
arc是ios4引入的一項新技術(從ios5開始支援弱引用),其使用與mrr&mrc相同的記憶體管理規則來管理記憶體,不過編譯器會在編譯階段自動的插入retain、release和autorelease等記憶體管理**來管理記憶體不再需要程式人員手動管理.非常方便,所以現在用的都是arc模式
多人開發時需要注意的
1> 使用analyze進行**的靜態分析
2> 為避免不必要的麻煩, 多人開發時盡量使用arc
和mrc相比消除了手動管理記憶體的煩惱,不需要手動呼叫retain,release和aytorelease等方法來管理記憶體
編譯器還會在適當的位置上插入**
在arc和mrc的屬性修飾符
strong用於oc物件,相當於mrc中的retain
weak用於oc物件,相當於mrc中的assign
assign用於基本資料型別,相當於mrc中的assign
在什麼情況下會發生記憶體洩露
1> 當程式在申請記憶體後,無法釋放已申請的記憶體空間(例如乙個物件或者變 量使用完成後沒有釋放,這個物件一直占用著記憶體),一次記憶體洩露危害 可以忽略,但記憶體洩露堆積後果很嚴重,無論多少記憶體,遲早會被占光。
2> 記憶體洩露會最終會導致記憶體溢位! 當程式在申請記憶體時,沒有足夠的記憶體空間供其使用,出現out of memory;比如申請了乙個int,但給它存了long才能存下的數,那就是記憶體溢位。
ios記憶體管理之copy
概述 copy(複製、拷貝)是產生乙個副本物件的過程,只要是通過拷貝產生的副本物件,副本物件中的內容與源物件中的內容就完全一致,下面介紹幾個copy相關的知識點
copy的特點
修改源物件的屬性和行為,不會影響副本物件
修改副本物件的屬性和行為,不會影響源物件
copy與mutablecopy
使用copy產生的副本物件是不可變的(如nsstring,nsarray)
使用mutablecopy產生的副本物件是可變的(如nsmutablestring,nsmutablearray)
通過拷貝是否會產生新的物件
通過拷貝是否會產生新物件,就要看源物件與副本物件是否滿足拷貝的特點
可變物件通過mutablecopy,會生成新的物件
可變物件通過copy,會生成新的物件
不可變物件通過mutablecopy,會生成新的物件
不可變物件通過copy,不會生成新的物件(因為源物件與副本物件都是不可變的,已經滿足拷貝的特點)
深拷貝(內容拷貝)與淺拷貝(指標拷貝)
深拷貝: 如果通過拷貝生成了新物件,就稱為深拷貝(內容拷貝)
淺拷貝: 如果通過拷貝沒生成新物件,就稱為淺拷貝(指標拷貝)
C 記憶體管理詳解
偉大的bill gates 曾經失言 640k ought to be enough for everybody bill gates 1981 程式設計師們經常編寫記憶體管理程式,往往提心吊膽。如果不想觸雷,唯一的解決辦法就是發現所有潛伏的地雷並且排除它們,躲是躲不了的。本文的內容比一般教科書的要...
C 記憶體管理詳解
踏入c 中的雷區 c 記憶體管理詳解 這篇文章回答了我之前的乙個問題,就是分配記憶體用malloc好,還是用new好,今天跑程式的時候,發現malloc老是失敗,氣得不行,最後看到了這篇文章,原來如此,以後堅決用new了。1 有了malloc free為什麼還要new delete?malloc與f...
iOS 記憶體管理詳解
在arc下主要有以下幾個關鍵字 1.關鍵字 strong 預設值,表示只要有強引用指標指向該變數,則該變數會一直存在。2.關鍵字 weak 弱引用,表示若沒有任何強引用指標指向該變數,會自動將變數的值置為空,即nil狀態。3.關鍵字 autoreleasing 用於標示自動釋放的變數 4.關鍵字 u...