關於內存管理,寫一個簡單易懂的教程

【ios】關於內存管理,寫一個簡單易懂的教程  

2012-06-28 15:39:39|  分類: ios內存管理 |  標籤: |字號 訂閱

管理原則:

誰用誰retain,誰retain的誰release。

複製代碼
1 ClassA *obj1 = [[ClassA alloc] init];  2 //這裏你申請了一塊內存地址,指針obj1指向了這塊內存地址,同時你給它retain了一下(retain,copy,alloc這幾個方法都相當於把retaincount加一),此時obj1所指向的這塊內存地址retaincount爲1。 3  4 ClassA *obj2=obj1; 5 [obj2 retain]; 6 //obj1和obj2同時都指向了上面所述的內存地址,我假設這塊內存爲A,那麼A這塊內存的retaincount爲2。 7 [obj1 release]; 8 [obj2 release]; 9 //最後不用的時候,需要釋放了
複製代碼

二、不要隨便看到retaincount多就給它釋放
很多朋友在學完內存管理後喜歡玩消除,不該釋放的他去釋放,舉個例子

UIViewController *ct1=[[UIViewController alloc] init]; [self.navigationcontroller pushViewController:ct1 animated:YES]; [ct1 relese];

 

這 裏,初始化一個viewcontroller,然後用導航push進來,最後釋放這個viewcontroller,很多人在這裏操作完畢後,繼續打印 ct1的retaincount,發現它的retaincount不爲0,就繼續release,這裏是非常錯誤的方法,直接導致程序崩潰,繼續看以上原 則“誰用誰retain,誰retain的誰release”,你用的時候,初始化,並retain了一次,最後你release了一次,到此結束!之後 不管你發現它的retaincount爲幾,你都不該再release。你打印出來的retaincount並不是你retain的,而是系統框架本身 retain的,由框架本身來處理,開發者不必理會。
類似還有很多,數組的addobject、addsubview等等很多方法,都是框架自己家retain的,開發者本身retain後release,不必理會它的retaincount。
另 外插一句,如果是多人協同開發,這種情況最容易碰到,別人傳遞一個參數過來,你拿過來retain後使用,使用完畢release,發現 retaincount還不是0,於是你繼續release,這樣你就把你同伴retain的計數給release掉了,當他下次使用的時候發現崩潰了, 這種情況會讓你的團隊浪費無數的時間來找原因。
三、關於屬性
屬性在.h文件中是這樣聲明的

@property(nonatomic,retain) Class *obj;

括號內第二個參數代表的意義是什麼呢?
我們分析一下他內部的機制
@property (retain) Class* obj;@synthesize obj;實際上是gettersetter,有retain參數的property,內部代碼如下

複製代碼
-(Class *) getObj {          return obj; }  -(void) setObj:(Class *) value {          if (obj != value)          {                    [obj release];                    obj = [value retain];          } }
複製代碼

願意仔細分析的童鞋可以仔細研究一下,不太明朗的童鞋請聽我說。

這個屬性定義以後如何使用呢?我們只說賦值(也就是set)

self.obj=xxx; [self setObj:xxx]; obj=xxx;


賦值方法有以下幾種,其中前兩個是相同的,都是調用了setObj:方法同時也就導致了obj的retaincount增加了1,而第三個賦值方法並沒有增加retaincount,只是將指針指向了xxx內存地址。
所以大家賦值時可以這樣

Class *c=[[Class alloc] init]; self.obj=c;[c release]; //或者 Class *c=[[Class alloc] init]; [self setObj:c];[c release]; //或者 Class *c=[[Class alloc] init];obj=c;

 

屬 性的這個機制是讓你在整個self裏(也就是當前類的實例裏)一直保留這個obj的retaincount,所以你必須在此類的dealloc裏將obj 的retaincount置零(你只需要release,如果你嚴格遵守“誰用誰retain,誰retain的誰release”的話)

-(void)dealloc {     [obj release];     [super dealloc]; }
這裏,其實我主要要說明的就是屬性的賦值方式用self.xxx=xxxx和xxx=xxxx是完全不同的賦值方式,大家切記!
四、autorelease對象
autorelease 對象就是自動釋放對象,大家可能會疑惑,能自動釋放,我還管理幹嘛,我都用自動釋放算了,事實不是這樣的,自動釋放確實好用,但是自己管理內存才能讓項目 佔用更小的資源,跑起來更流暢,大家可以手動管理加autorelease一起來使用,我先講解一下autorelease對象到底是什麼個情況。
首先,告訴大家autorelease對象什麼時候纔會被釋放。
在main函數裏有一個autorelease pool,自動釋放池,所以在這個自動釋放池裏的autorelease對象都會在自動釋放池結束的時候全部被釋放。
大 家可能會問了,“難道所有的autorelease對象都是在程序退出的時候才被釋放?”,答案當然不是,其實main函數中只是一個程序中衆多自動釋放 池中的一個,每個runloop都會隱性的創建一個自動釋放池,啥是一個runloop?每個UIView創建、delegate回調等等都會創建一個自 動釋放池,記得這個“等等”,意思就是有很多(如果大家想要詳細瞭解runloop,可以去google)。所以大家不用擔心autorelease對象 不會被釋放。
很 多系統的方法,比如[NSArray array]、[NSString stringformat]等等返回的對象都是autorelease對象,這些對象是不需要手動釋放的,如果手動釋放會導致程序崩潰!切記!,原則就是 系統中所有沒有使用alloc、copy、retain來創建的對象都是autorelease對象,大家千萬別手動release
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章