关于OC的内存管理-01
1.什么是內存管理?
大家都知道手機的內存是有限的,app應用的內存也應該是受限制的,隨著app應用的使用會導致內存的占用率增大。當內存占用率達到一種程度時。系統會發出內存警告。這時我們須要把一些不用的對象和變量所占用的內存釋放掉,也就是說我們須要手動對內存進行管理。
而我們管理的范圍:不論什么繼承了NSObject 的對象,對于基本數據類型(比方float、int 、char、struct、enum等)則是無效的。
2.怎樣進行內存管理
1)每一個OC對象本身就有一個占用4個字節內存的計數器,它存儲的是一個整數。表示“當前對象被引用的次數”。當對象一被建立的時候(比如alloc、new、copy)就默覺得1。而計數器的作用就是,當對象的計數器為0時,當前對象就會被系統回收,假設計數器不為0,程序的整個運行過程中,當前對象的內存就一直不回被回收
2)引用計數器的三種操作
(1)retain(給對象發送消息一條retain消息) ? 計數器+1,有返回值,返回的是對象本身
(2)release (給對象發送消息一條release消息)計數器-1。無返回值。
(3)retainCount (給對象發送消息一條retainCount消息)獲取當前對象的引用計數器值
3.當對象銷毀時系統會自己主動調用dealloc方法,dealloc方法就像臨終遺言一樣,所以我們一般重寫dealloc方法
而且此方法中,一定要有[super dealloc] ,且一定放在最后面。
3.如果我們有一個Person 類
#import <Foundation/Foundation.h >
@interface Person : NSObject
{
{
int _age ;
}
-(void)setAge:(int)age;
-(int)age;
}
#import"Person.h"
@implementation Person
{
-(void)setAge:(int)age{
_age = age ;
}
-(int)age{
return _age;}
-(void)dealloc{
NSLog(@"Person 對象被回收");
[super dealloc]。
}
(1)第一種情況
int main(){
//當我們一調用alloc時,對象計數器就默覺得1。所以一有alloc ,我們須在后面加上[對象名 release]
//p-1(當前計數器為1)
Person *p =[[Person alloc] init];
//p-2(當前計數器為2)
[p retain];
//release表示計數器減1,此時p-1
[p ?release];
//p-0,這時系統會回收對象p ,運行對象p的dealloc方法
[p ?release];
return 0;
}
(2)另外一種情況
int main(){
//當我們一調用alloc時,對象計數器就默覺得1。
所以一有alloc ,我們須在后面加上[對象名 release]
//p-1(當前計數器為1)
Person *p =[[Person alloc] init];
//p-2(當前計數器為2)
[p retain];
//release表示計數器減1,此時p-1
[p ?release];
//p-0,這時系統會回收對象p 。運行對象p的dealloc方法
[p ?release]。
//特別。此時系統已把對象p回收,假設我們在這里再多次運行[p release]的話
//會訪問僵尸對象(已被系統回收的對象,一塊不可用的內存)
//而p這時則叫野指針(指向僵尸對象的指針),會造成壞的訪問即EXC_BAD_ACCESS
return 0;
}
如圖:
(3)第三種情況
int main(){
//當我們一調用alloc時,對象計數器就默覺得1。所以一有alloc ,我們須在后面加上[對象名 release]
//p-1(當前計數器為1)
Person *p =[[Person alloc] init];
//p-2(當前計數器為2)
[p retain];
//release表示計數器減1,此時p-1
[p ?release];
//p-0。這時系統會回收對象p ,運行對象p的dealloc方法
//運行此句的話。假設不打開Enable Zoombie Object 則不會報錯
//假設打開的話。則會出現這種提示錯誤
//message send to deallocated instance
//意思是給已經回收的實例發送消息
p.age = 10;
return 0;
}
如圖:(4)第四種情況;
int main(){
//當我們一調用alloc時,對象計數器就默覺得1。所以一有alloc ,我們須在后面加上[對象名 release]
//p-1(當前計數器為1)
Person *p =[[Person alloc] init];
//p-2(當前計數器為2)
[p retain];
//release表示計數器減1,此時p-1
[p ?release];
[p ?release];
//結合第三種情況。我們就會這樣想,這時計數器本來是0,我們能夠運行retain。計數器+1
//我們不就能夠成功運行p.age = 10;了嗎 其實,回收的對象是不可能死而復生的。
//運行的結果如上圖。
//message send to deallocated instance
//意思是給已經回收的實例發送消息
p.age = 10;
return 0;
}
總結
以上是生活随笔為你收集整理的关于OC的内存管理-01的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PHP 用each 和list配合 达到
- 下一篇: PHP设计模式系列 - 解释器模式