浅析Objective-C内存管理

来源:互联网 发布:免费的网络推手 编辑:程序博客网 时间:2024/05/19 13:06

在Xcode4.2及之后的版本中已经引入了引入了ARC(Automatic Reference Counting)机制,程序编译时Xcode可以自动给你的代码添加内存释放代码。如果不使用arc机制就需要自己来进行内存管理了。

objective-c的内存管理机制使用的是引用计数器的原理。

当一个对象在创建之后它的引用计数器为1,当调用这个对象的alloc、retain、new、copy方法之后引用计数器自动在原来的基础上加1,当调用这个对象的release方法之后它的引用计数器减1,如果一个对象的引用计数器为0,则系统会自动调用这个对象的dealloc方法来销毁这个对象。

#import <Foundation/Foundation.h>#import "HPPStudent.h"int main(int argc, const char * argv[]) {    @autoreleasepool {        HPPStudent *stu1 = [[HPPStudent alloc] init];// 调用alloc方法,引入计数+1        NSLog(@"引用计数为:%d",[stu1 retainCount]);// retainCount为1        HPPStudent *stu2 = [stu1 retain];        NSLog(@"引用计数为:%d",[stu1 retainCount]);// retainCount为2        [stu1 release];        NSLog(@"引用计数为:%d",[stu2 retainCount]);// retainCount为1        [stu2 release];    }    return 0;}

另外,怎么知道对象是否被释放呢?

对象释放的时候通常会调用dealloc方法

#import <Foundation/Foundation.h>@interface HPPStudent : NSObject {    NSString *name;}- (void) setName:(NSString *)_name;- (NSString *)name;@end
#import "HPPStudent.h"@implementation HPPStudent- (void)dealloc{    NSLog(@"%@ dealloc", name);    [super dealloc];//注意最后一定要调用父类的dealloc方法(两个目的:一是父类可能有其他引用对象需要释放;二是:当前对象真正的释放操作是在super的dealloc中完成的)}- (void) setName:(NSString *)_name {    if (_name != name) {//首先判断要赋值的变量和当前成员变量是不是同一个变量        [name release];//释放之前的对象        name = [_name retain];//赋值时重新retain    }}- (NSString *)name {    return name;}@end

属性参数@property和@synthesize

在上面的类的实现了,我们实现了getter和setter方法,实现了这个两个方法之后,我们就直接通过点运算符来访问对象并且进行对象的操作。

#import <Foundation/Foundation.h>#import "HPPStudent.h"int main(int argc, const char * argv[]) {    @autoreleasepool {        HPPStudent *stu1 = [[HPPStudent alloc] init];        stu1.name = @"mirhunana"; //使用点运算符    }    return 0;}

其实,使用@property就可以自动添加getter、setter的声明,这样我们就不需要自行实现了。

#import <Foundation/Foundation.h>@interface HPPStudent : NSObject //当编译器遇到@property时,会自动展开成getter和setter的声明@property (nonatomic,retain)NSString *name;@end

@synthesize可以自动添加getter、setter的实现

#import "HPPStudent.h"@implementation HPPStudent@synthesize name;- (void)dealloc{    NSLog(@"%@ dealloc", name);    [super dealloc];//注意最后一定要调用父类的dealloc方法(两个目的:一是父类可能有其他引用对象需要释放;二是:当前对象真正的释放操作是在super的dealloc中完成的)}@end

这里使用@property和@synthesize的效果跟上面直接实现getter和setter的效果是相同的。

另外,我们可以看到,在声明中对属性也加了关键词进行修饰。

@property (nonatomic,retain)NSString *name;

对于属性或者变量的定义,我们可以使用关键词进行修饰。

有下面基类关键字:

这里写图片描述

@property的参数默认参数:(atomic,readwrite,assign)

assign,用于基本数据类型

-(void)setA:(int)a{    _a=a;}

retain,通常用于非字符串对象

-(void)setA:(Car *)a{    if(_a!=a){        [_a release];        _a=[a retain];    }}

copy,通常用于字符串对象、block、NSArray、NSDictionary

-(void)setA:(NSString *)a{    if(_a!=a){        [_a release];        _a=[a copy];    }}

自动释放池

自动释放池就是将自动内存释放使用@autoreleasepool关键字声明一个代码块,如果一个对象在初始化时调用了autorelase方法,那么当代码块执行完之后,在块中调用过autorelease方法的对象都会自动调用一次release方法。

#import <Foundation/Foundation.h>#import "HPPStudent.h"int main(int argc, const char * argv[]) {    @autoreleasepool {        HPPStudent *person= [[[HPPStudent alloc] init] autorelease];//调用了autorelease方法,在autoreleasepool块结束位置会自动该对象进行释放操作        person.name = @"mirhuanan";    }    return 0;}

参考文章:iOS开发系列—Objective-C之内存管理

0 0
原创粉丝点击