一.記憶體分為五大區 :棧區,堆區,全域性區,常量區,**區
2.棧區特點:
3.堆區的特點
4.常量區的特點
5,全域性區 特點
二.記憶體管理
1.manul reference count & auto reference count (mrc &arc) referencecount 引用計數 系統根據引用計數的個數來**記憶體
要注意 引用計數 是為了管理記憶體 (1.防止出現野指標. 2.防止記憶體洩露)
2.幾個記憶體管理的要用到的方法:+ alloc -retain -release -copy -autorelease
(1) +alloc (referencecount)由0-1的過程
(2) -retain ( +1 返回位址 )
person *person1=[person retain]; person 所指物件的引用計數加一
(3)-release (-1 無返回值 )
[person1 release]; person1所指物件的引用計數減一
(4)-copy (本身引用計數不變,副本引用計數加一 返回新位址)
person *p2=[p copy];p 所指物件的引用計數不變 p2所指物件的引用計數加一
(5)-autorelease 在將來的某個時間將引用計數減一 注意 autorelease 之後 對系那個的 retaincount 不會馬上減一 而是在將來某個時間減一 (這取決於他處於的 autoreleasepool什麼時候釋放).
3.delloc 是由父類繼承過來的類,有系統自動呼叫,當 物件 的引用計數值為0時,系統會自動呼叫 delloc (自己可以重寫個 delloc 方法用於判斷物件是否銷毀);
注意的一點是[super delloc]表示現在要呼叫從父類繼承過來的 delloc 方法 (注意 :這一句話要放在方法體的最後邊);
在 dealloc 方法中要將所有 有retain屬性 的例項變數 都 release 然後要使用[super dealloc]; 4.
autoreleasepool 的工作原理 就像乙個棧,哪個物件先被放進 pool ,哪個物件就最後 release (棧中存的是物件的位址,即這一塊要釋放的記憶體的位址)
autoreleasepool 目前的建立方式是@ autoreleasepool
autoreleasepool中可以巢狀多個 autoreleasepool{}以便釋放在程式中多次出現的有 autorelease 方法 的物件,避免記憶體空間不足,造成洩露.
5.記憶體管理的原則:
(1).引用計數的增加和減少相等,當引用計數降為0之後,不應該再使用這塊記憶體
(2).凡是使用(要理解為看到了,沒有看到就不減)了 alloc,retain,或者 copy 讓記憶體的引用計數增加了,就需要使用 release或者 autorelease 讓記憶體的引用計數減少.在一段**內,增加和減少的次數要相等.當引用計數值為0 時 ,物件所佔的記憶體,就被系統**
(3).在乙個中referencecount 的增加的次數要和減少的次數一樣.有兩個原因:
(4) 在乙個
內如果有明顯的出現了
alloc retain copy,
則一定要在這段**結束之前
release.
要保證每乙個
{}中的+和
-平衡.如果沒有明顯的出現
,就不要用
release,
比如便利構造器
(它的釋放
最好是在自己的實現體中
用autorelease
延遲釋放 );
6.copy 屬性: 當乙個類要使用 copy時, 生成自己的關於那個物件的副本 就一定要實現 nscopying 協議 並且實現 nscopying 協議中的 - copywithzone:方法 .
並且在這個方法中自己實現 copy 的細節 一般式要建立乙個新的物件,將 self 的值賦給這個物件 然後返回這個物件的位址
例:@inte***ce person:nsobject
……..
@end
@implementation person
- (id)copywithzone:(nszone *)zone
@end
person *p=[[person alloc] initwithname:self.name age:self.age gender:self.gender];
person *p2=[p copy];
copy
內部的alloc
不在內部釋放
不然在外面看到
copy
時會又釋放
一次注意:如果 沒有實現 nscopying 協議 而直接使用 copy 方法 就會引發crash
不是任何物件都可以接收 copy 訊息只有接受了 nscopying 協議的物件才能接收 copy 訊息
7.關於淺拷貝 與 深拷貝
淺拷貝 與 深拷貝 根據自己的理解 其實並沒有乙個完整的定論.
一般的理解是 淺拷貝-----只是實現了」指標" 的拷貝 (內容共用,乙個物件中內容的改變 會 導致另乙個物件中內容的改變)
深拷貝—---至少有一層物件實現了產生物件的副本 (內容不共用, 乙個物件中內容的改變,不會影響另乙個物件)
完全拷貝———每一層都實現了物件的副本的產生(類中每乙個例項變數都實現了深拷貝(每一層物件都是))
其實 關於深拷貝 與淺拷貝 只是乙個理解或者概念上的問題 不需要深究什麼是深拷貝,什麼是淺拷貝 他們只是幾種拷貝方式
8.如果出現
兩個物件相互引用的情況(如: husband 中存在 wife 物件 ,wife 中存在 husband 物件) 此時物件作為例項變數的屬性的 attribute 的設定不應該兩個物件同時都設定為 retain 或 copy, 否則會造成 retain cycle ,導致兩個物件都無法 dealloc . 解決辦法是將乙個類的例項變數設定為 assign 表示弱引用, 但這種方法要注意記憶體管理與野指標情況.
同時要注意
**委託的情況,當出現**的情況的時候,**的語義屬性要設定為 assign 防止**與其委託之間的迴圈引入,而導致無法釋放
最終乙個設定語義屬性的乙個基本規則是: 屬性的型別凡是沒有帶 * 都要設定為 assign (包括**的 id 型別);
我們常見的
delegate
往往是assign
方式的屬性而不是
retain
方式的屬性,賦值不會增加引用計數,就是為了防止
delegation
兩端產生不必要的迴圈引用。如果乙個
uitableviewcontroller 物件a
通過retain
獲取了uitableview物件b
的所有權,這個
uitableview物件b
的delegate又是a
,如果這個
delegate
是retain
方式的,那基本上就沒有機會釋放這兩個物件了。自己在設計使用
delegate
模式時,也要注意這點。
OC 記憶體管理初級
法則 如果對乙個物件進行了alloc retain copy之後,就擁有了該物件的所有權,就必須對它進行release或者autorelease alloc 引用計數0 1 retain 引用計數 立即 1 copy release 引用計數 立即 1 autorelease 配合 autorele...
OC記憶體管理初級演練
alloc 開闢記憶體空間,並且將物件的引用計數由0變1.person per1 person alloc init 0 1 retaincount 用來獲取當前物件的引用計數 nslog lu per1 retaincount retain 將物件的引用計數加一 person per2 per1 ...
oc的記憶體管理初級
建立乙個person類在.h,宣告屬性 凡是語義設定使用了retain copy的屬性,其對應的例項變數都需要在dealloc方法裡面release一次 property nonatomic copy nsstring hobby property nonatomic retain nsstring...