郝萌主倾心贡献,尊重作者的劳动成果,请勿转载。
如果文章对您有所帮助,欢迎给作者捐赠,支持郝萌主,捐赠数额随意,重在心意^_^
我要捐赠: 点击捐赠
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进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。