郝萌主傾心貢獻,尊重作者的勞動成果,請勿轉載。
如果文章對您有所幫助,歡迎給作者捐贈,支持郝萌主,捐贈數額隨意,重在心意^_^
我要捐贈: 點擊捐贈
Cocos2d-X×××:點我傳送
提供給Objective-C程序員的基本內存管理模型有以下三種:
1)自動垃圾收集。(iOS運行環境并不支持垃圾收集,在這個平臺開發程序時沒有這方面的選項,只能用在Mac OS X 程序上開發。這個機制挺惡心的,用mac電腦的人知道,當內存不足的時候,機器基本上就是卡死了。)
2)手工引用計數和自動釋放池。(這種方式,對程序員的要求很高。自己維護嘛,)
3)自動引用計數(ARC)。
#import <Foundation/Foundation.h> @interface Song : NSObject { NSString *title; NSString *artist; long int duration; } //操作方法 - (void)start; - (void)stop; - (void)seek:(long int)time; //訪問成員變量方法 @property NSString *title; @property NSString *artist; @property(readwrite) long int duration; //構造函數 -(Song*) initWithTitle: (NSString *) title andArtist: (NSString *) artist andDuration:( long int )duration ; @end實現如下:
#import "Song.h" @implementation Song @synthesize title; @synthesize artist; @synthesize duration; //構造函數 -(Song*) initWithTitle: (NSString *) newTitle andArtist: (NSString *) newArtist andDuration:(long int)newDuration { self = [super init]; if ( self ) { self.title = newTitle; self.artist = newArtist; self.duration = newDuration; } return self; } - (void)start { //開始播放 } - (void)stop { //停止播放 } - (void)seek:(long int)time { //跳過時間 } -(void) dealloc { NSLog(@"釋放Song對象..."); [title release]; [artist release]; [super dealloc]; } @end
#import <Foundation/Foundation.h> #import "Song.h" int main (int argc, const char * argv[]) { Song *song1 = [[Song alloc] initWithTitle:@"Big Big World" andArtist:@"奧斯卡.艾美莉亞" andDuration:180]; Song *song2 = [[Song alloc] initWithTitle:@"It's ok" andArtist:@"atomic kitten" andDuration:280]; // print current counts NSLog(@"song 1 retain count: %i", [song1 retainCount] ); NSLog(@"song 2 retain count: %i", [song2 retainCount] ); // increment them [song1 retain]; // 2 [song1 retain]; // 3 [song2 retain]; // 2 // print current counts NSLog(@"song 1 retain count: %i", [song1 retainCount] ); NSLog(@"song 2 retain count: %i", [song2 retainCount] ); // decrement [song1 release]; // 2 [song2 release]; // 1 // print current counts NSLog(@"song 1 retain count: %i", [song1 retainCount] ); NSLog(@"song 2 retain count: %i", [song2 retainCount] ); // release them until they dealloc themselves [song1 release]; // 1 [song1 release]; // 0 [song2 release]; // 0 return 0; }
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; … … [pool release];// [pool drain];
#import <Foundation/Foundation.h> int main (int argc, const char * argv[]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSArray *weeksNames1 = [NSArray arrayWithObjects: @"星期一",@"星期二",@"星期三",@"星期四" ,@"星期五",@"星期六",@"星期日",nil]; NSArray *weeksNames2 = [[NSArray alloc] initWithObjects: @"星期一",@"星期二",@"星期三",@"星期四" ,@"星期五",@"星期六",@"星期日",nil]; //[weeksNames1 release]; //[weeksNames1 autorelease]; //[weeksNames2 release]; //[weeksNames2 autorelease]; NSLog(@" retain count: %i" , [weeksNames1 retainCount] ); NSLog(@" retain count: %i" , [weeksNames2 retainCount] ); [pool release]; return 0; }
- (void) setTitle:(NSString *) newTitle { title = newTitle; } - (void) setArtist:(NSString *) newArtist { artist = newArtist; }
- (void) setTitle:(NSString *) newTitle { [newTitle retain]; [title release]; title = [[NSString alloc] initWithString: newTitle]; } - (void) setArtist:(NSString *) newArtist { [newArtist retain]; [artist release]; artist = [[NSString alloc] initWithString: newArtist]; }
- (void) setDuration:(long int) newDuration { duration = newDuration; }此外, 在構造方法中也必須要注意, 不能直接賦值title =newTitle, 而是要調用自身的設置方法:
//構造函數 -(Song*) initWithTitle: (NSString *) newTitle andArtist: (NSString *) newArtist andDuration:(long int)newDuration { self = [super init]; if ( self ) { [self setTitle:newTitle]; [self setArtist:newArtist]; [self setDuration:newDuration]; } return self; }
- (void) setTitle:(NSString *) newTitle { title = newTitle; }
(void) setTitle:(NSString *) newTitle { [newTitle retain]; [title release]; title = [[NSString alloc] initWithString: newTitle]; }
- (void) setTitle:(NSString *) newTitle { [newTitle copy]; [title release]; title = [[NSString alloc] initWithString: newTitle]; }
手工內存管理規則的總結:
1)如果需要保持一個對象不被銷毀,可以使用retain。在使用完對象后,需要使用release進行釋放。
2)給對象發送release消息并不會必須銷毀這個對象,只有當這個對象的引用計數減至0時,對象才會被銷毀。然后系統會發送dealloc消息給這個對象用于釋放它的內存。
3)對使用了retain或者copy、mutableCopy、alloc或new方法的任何對象,以及具有retain和copy特性的屬性進行釋放,需要覆蓋dealloc方法,使得在對象被釋放的時候能夠釋放這些實例變量。
4)在自動釋放池被清空時,也會為自動釋放的對象做些事情。系統每次都會在自動釋放池被釋放時發送release消息給池中的每個對象。如果池中的對象引用計數降為0,系統會發送dealloc消息銷毀這個對象。
5)如果在方法中不再需要用到這個對象,但需要將其返回,可以給這個對象發送autorelease消息用以標記這個對象延遲釋放。autorelease消息并不會影響到對象的引用計數。
6)當應用終止時,內存中的所有對象都會被釋放,不論它們是否在自動釋放池中。
7)當開發Cocoa或者iOS應用程序時,隨著應用程序的運行,自動釋放池會被創建和清空(每次的事件都會發生)。在這種情況下,如果要使自動釋放池被清空后自動釋放的對象還能夠存在,對象需要使用retain方法,只要這些對象的引用計數大于發送autorelease消息的數量,就能夠在池清理后生存下來。
自動引用計數(ARC):
強變量,通常,所有對象的指針變量都是強變量。
如果想聲明強變量,可以使用__strong Faction *fl;這樣的__strong來修飾。
值得注意的是,屬性默認不是strong,其默認的特性是unsafe_unretained類似assign。
所以需要聲明屬性strong時,可以如下:
@property (strong, nonatomic) NSMutableArray *birdNames;
編譯器會保證在事件循環中通過對賦值執行保持操作強屬性能夠存活下來。
帶有unsafe_unretained(相當于assign)或weak的屬性不會執行這些操作。
弱變量,可以使用__week關鍵字來聲明。弱變量不能阻止引用的對象被銷毀。
當引用的對象釋放時,弱變量會被自動設置為nil。
需要注意的是,在iOS4和Mac OS V10.6中不支持弱變量。
在這種情況下,你仍然可以為屬性使用unsafe_unretained, assing特性.
ARC都會在“底層”發生,所以一般不用關心。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。