person類 -----》.h文件
讓客戶滿意是我們工作的目標,不斷超越客戶的期望值來自于我們對這個行業的熱愛。我們立志把好的技術通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領域值得信任、有價值的長期合作伙伴,公司提供的服務項目有:主機域名、雅安服務器托管、營銷軟件、網站建設、尼河口網站維護、網站推廣。#import <Foundation/Foundation.h> @interface Person : NSObject<NSCopying> //使用copy必須引入NSCopying協議。。。 // 語義設置 //1.NSString接收了copy協議, //2.大多數規范化 @property (nonatomic , copy)NSString *name; @property (nonatomic , assign)NSInteger age; @property (nonatomic , retain)NSString *sex; @property (nonatomic , copy)NSString *hobby; @property (nonatomic , assign)NSInteger num; #pragma mark ---自定義初始化方法 - (instancetype)initWithName:(NSString *)name age:(NSInteger)age hobby:(NSString *)hobby sex:(NSString *)sex num:(NSInteger)num; @end
person類 -----》.m文件
#import "Person.h" @implementation Person @synthesize name = _name; @synthesize age = _age; @synthesize hobby = _hobby; @synthesize sex = _sex; @synthesize num = _num; - (void)setName:(NSString *)name { if (_name != name) { [_name release]; _name = [name copy]; } } - (NSString *)name { return [[_name retain] autorelease]; } - (void)setAge:(NSInteger)age { _age = age; } - (NSInteger)age { return _age; } - (void)setSex:(NSString *)sex { if (_sex != sex) { [_sex release]; _sex = [sex retain]; } } - (NSString *)sex { return [[_sex retain] autorelease]; } - (void)setHobby:(NSString *)hobby { if (_hobby != hobby) { [_hobby release]; _hobby = [hobby copy]; } } - (NSString *)hobby { return [[_hobby retain] autorelease]; } - (void)setNum:(NSInteger)num { _num = num; } - (NSInteger)num { return _num; } - (instancetype)initWithName:(NSString *)name age:(NSInteger)age hobby:(NSString *)hobby sex:(NSString *)sex num:(NSInteger)num { self = [super init]; if (self) { [self setName:name];//1.0過度版 self.name = name; //2.0終極版 // _age = age; [self setAge:age];//1.0 self.age = age; //2.0 self.sex = sex; self.hobby = hobby; self.num = num; } return self; } - (void)dealloc { NSLog(@"內存被回收了"); [super dealloc]; } - (id)copyWithZone:(NSZone *)zone //假拷貝 { //1. // return self; //2.0 // return [self retain]; //淺拷貝 // Person *p = [[Person alloc] initWithName:self.name age:self.age hobby:self.hobby sex:self.sex num:self.num]; // return p; //深拷貝 Person *p = [[Person alloc] initWithName:self.name age:self.age hobby:self.hobby sex:self.sex num:self.num]; p.name = [self.name copy]; // p.age = [self.age copy]; p.hobby = [self.hobby copy]; p.sex = [self.sex copy]; // p.num = [self.num copy]; return p; } @end
main.m文件。。。。。。
#import <Foundation/Foundation.h> #import "Person.h" int main(int argc, const char * argv[]) { @autoreleasepool { //alloc 開辟內存空間,讓被開辟的內存空間的引用計數變為1 Person *p = [[Person alloc] init]; p.name = @"liuyafang"; p.age = 25; p.sex = @"男"; p.hobby = @"女"; p.num = 201010; //retain 引用計數加1,如果內存空間之前引用計數為1,retain之后變為2 [p retain]; Person *meiren = p; // release在1后,從1->0的時候,自動調用dealloc方法,來回收內存。dealloc時繼承自父類的方法,當對象引用計數為0的時候,由對象自動調用 [p release]; NSLog(@"%@,%ld", p.name , [p retainCount]);//alloc開辟內存空間。0->1 Person *pp = [p retain]; //即指向,又擁有。 [p release]; [pp retain]; pp.name = @"pp"; NSLog(@"%ld,%@", [pp retainCount],pp.name); [pp release]; Person *liu = pp ; [liu retain]; liu.name = @"劉亞方"; NSLog(@"%@,%ld",liu.name , [p retainCount]); [liu release]; //autorelease,未來的某一時刻引用計數減1,這里的某一時刻指在出去autoreleasePool后。 //通過autoreleasepool控制autorelease對象的釋放 //向一個對象發送autoresease消息,這個對象何時釋放,取決于autoreleasepool Person *liuyafang = [[Person alloc] init]; [liuyafang retain]; [liuyafang retain]; [liuyafang retain]; // [liuyafang release]; NSLog(@"liuyafang:%ld", [liuyafang retainCount]); [liuyafang autorelease]; NSLog(@"liuyafang-->%ld", [liuyafang retainCount]); //autorelease只有出去autoreleasepool 之后才能-1才能使用 Person *zhenzi = [[Person alloc] initWithName:@"疹子" age:25 hobby:@"吃人" sex:@"男" num:36]; Person *L = [zhenzi copy]; } //這個是老方法NSAutoreleasePool Person *liuyafang = [[Person alloc] init]; [liuyafang retain]; [liuyafang retain]; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; //autorelease老用法 。。。 [liuyafang autorelease]; [pool release]; NSLog(@"%ld", [liuyafang retainCount]); return 0; }
一、基本原理
(一)為什么要進行內存管理。
由于移動設備的內存極其有限,所以每個APP所占的內存也是有限制的,當app所占用的內存較多時,系統就會發出內存警告,這時需要回收一些不需要再繼續使用的內存空間,比如回收一些不再使用的對象和變量等。
管理范圍:任何繼承NSObject的對象,對其他的基本數據類型無效。
本質原因是因為對象和其他數據類型在系統中的存儲空間不一樣,其它局部變量主要存放于棧中,而對象存儲于堆中,當代碼塊結束時這個代碼塊中涉及的所有局部變量會被回收,指向對象的指針也被回收,此時對象已經沒有指針指向,但依然存在于內存中,造成內存泄露。
(二)對象的基本結構
每個OC對象都有自己的引用計數器,是一個整數表示對象被引用的次數,即現在有多少東西在使用這個對象。對象剛被創建時,默認計數器值為1,當計數器的值變為0時,則對象銷毀。
在每個OC對象內部,都專門有4個字節的存儲空間來存儲引用計數器。
(三)引用計數器的作用
判斷對象要不要回收的唯一依據就是計數器是否為0,若不為0則存在。
(四)操作
給對象發送消息,進行相應的計數器操作。
Retain消息:使計數器+1,改方法返回對象本身
Release消息:使計數器-1(并不代表釋放對象)
retainCount消息:獲得對象當前的引用計數器值
(五) 對象的銷毀
當一個對象的引用計數器為0時,那么它將被銷毀,其占用的內存被系統回收。
當對象被銷毀時,系統會自動向對象發送一條dealloc消息,一般會重寫dealloc方法,在這里釋放相關的資源,dealloc就像是對象的“臨終遺言”。一旦重寫了dealloc方法就必須調用[super dealloc],并且放在代碼塊的最后調用(不能直接調用dealloc方法)
一旦對象被回收了,那么他所占據的存儲空間就不再可用,堅持使用會導致程序崩潰(野指針錯誤)。
二、相關概念和使用注意
野指針錯誤:訪問了一塊壞的內存(已經被回收的,不可用的內存)。
僵尸對象:所占內存已經被回收的對象,僵尸對象不能再被使用。(打開僵尸對象檢測)
空指針:沒有指向任何東西的指針(存儲的東西是0,null,nil),給空指針發送消息不會報錯
注意:不能使用[p retaion]讓僵尸對象起死復生。
三、內存管理原則
(一)原則
只要還有人在使用某個對象,那么這個對象就不會被回收;
只要你想使用這個對象,那么就應該讓這個對象的引用計數器+1;
當你不想使用這個對象時,應該讓對象的引用計數器-1;
(二)誰創建,誰release
(1)如果你通過alloc,new,copy來創建了一個對象,那么你就必須調用release或者autorelease方法
(2)不是你創建的就不用你去負責
(三)誰retain,誰release
只要你調用了retain,無論這個對象時如何生成的,你都要調用release
(四)總結
有始有終,有加就應該有減。曾經讓某個對象計數器加1,就應該讓其在最后-1.
另外有需要云服務器可以了解下創新互聯scvps.cn,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業上云的綜合解決方案,具有“安全穩定、簡單易用、服務可用性高、性價比高”等特點與優勢,專為企業上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。
分享題目:內存管理初級基礎--代碼-創新互聯
分享路徑:http://vcdvsql.cn/article34/csedse.html
成都網站建設公司_創新互聯,為您提供電子商務、域名注冊、云服務器、網站建設、企業建站、網頁設計公司
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯