set内存管理

来源:互联网 发布:巨人网络待遇 编辑:程序博客网 时间:2024/06/06 01:36


set 方法的内存管理


如果你有个OC对象类型的成员变量,就必须管理这个成员变量的内存。比如有个Car *_car
一、计数器的基本操作
1> retain : +1
2> release :-1
3> retainCount : 获得计数器


二、set方法的内存管理
1> set方法的实现
- (void)setCar:(Car *)car
{
    if ( _car != car )                               //首先判断一下,传进来的车是不是新车
    {
        [_car release];                              // 旧车 release 一次;
        _car = [car retain];                         // 新车 retain  一次,
     }
}


2> dealloc方法的实现(不要直接调用dealloc)            
- (void)dealloc                                      
{
    [_car release];                                 
    [super dealloc];
}
-------------------------------------------------------------------------
看下面这个例子
void test()
{
    
    Person *p = [[Person alloc] init]; //  创建一个Person对象,p指向该对象 用p来操作,p的年龄为20;p的计数器为现在为1
    p.age = 20;                        
    
    Car *c1 = [[Car alloc] init];     //  创建一个Car对象,c1指向该对象 用c1来操作,车的速度是250;c1的计数器为1 
    c1.speed = 250;                
    p.car = c1;                       //调用p的 setCar 把c1给p   c1的计数器+1   现在变为2
    
    Car *c2 = [[Car alloc] init];     //创建一个Car对象,c2指向该对象 用c2来操作,车的速度是300;c1的计数器为1 
    c2.speed = 300;
    p.car = c2;                       //把c1换成了c2, 因为p的_cer指向了c2,说以c1的计数器得-1, c2的计数器就+1. 现在c1的计数器是1,c2的计数器是2
    
    [c2 release];                     // c2的计数器-1, 现在变为1
    [c1 release];                     // c1为计数器-1,变为0, c1释放, 执行dealloc


    [p release];                      // p计数器-1, P释放,执行dealloc 把p以前所拥有的c2的计数器-1, 释放p2;
}


运行结果是:


[1905:303] 速度为250的Car对象被回收回
[1905:303] 速度为300的Car对象被回收了
[1905:303] 20岁的Person对象被回收了


@implementation Person
- (void)setCar:(Car *)car
{
    if (car != _car)
    {
        
        [_car release];                // 对当前正在使用的车(旧车)做一次release
        
        
        _car = [car retain];          // 对新车做一次retain操作
    }
}
- (Car *)car
{
    return _car;
}


- (void)setAge:(int)age

    _age = age;                      // 基本数据类型不需要管理内存
}
- (int)age
{
    return _age;
}


- (void)dealloc
{                                       
    [_car release];                   //在人挂掉以后, 把它以前所拥有的车做一次[_release]
    
    NSLog(@"%d岁的Person对象被回收了", _age);
    
    [super dealloc];
}


@end


@implementation Car
- (void)setSpeed:(int)speed
{
    _speed = speed;
}
- (int)speed
{
    return _speed;
}


- (void)dealloc
{
    
    NSLog(@"速度为%d的Car对象被回收了", _speed);
    
    [super dealloc];
}
@end


--------------------------------------------------------------------------------------------------------------------------------
控制set方法的内存管理


retain : release旧值,retain新值(用于OC对象)
assign : 直接赋值,不做任何内存管理(默认,用于非OC对象类型)
copy   : release旧值,copy新值(一般用于NSString *)
 
控制需不需生成set方法
readwrite :同时生成set方法和get方法(默认)
readonly  :只会生成get方法
 


多线程管理
atomic    :性能低(默认)
nonatomic :性能高
 
控制set方法和get方法的名称
setter : 设置set方法的名称,一定有个冒号:
getter : 设置get方法的名称


@property参数
1> OC对象类型
@property (nonatomic, retain) 类名 *属性名;
@property (nonatomic, retain) Car *car;
@property (nonatomic, retain) id car;


// 被retain过的属性,必须在dealloc方法中release属性
- (void)dealloc
{
    [_car release];
    [super dealloc];
}


2> 非OC对象类型(int\float\enum\struct)
@property (nonatomic, assign) 类型名称 属性名;
@property (nonatomic, assign) int age;


四、autorelease
1.系统自带的方法中,如果不包含alloc、new、copy,那么这些方法返回的对象都是已经autorelease过的
[NSString stringWithFormat:....];
[NSDate date];


2.开发中经常写一些类方法快速创建一个autorelease的对象
* 创建对象的时候不要直接使用类名,用self
-----------------------------------------------------------------------------------------------------------------------
看下面的例子
int main()
{
    
    User *u = [[User alloc] init];          //   u 的计数器是1
    u.name = @"小明";
    
    User *u2 = [[User alloc] init];         //   u2的计数器是1
    u2.name = @"小花";
    
    
    Status *s = [[Status alloc] init];      //   s的计数器是1
    s.text = @"今天天气真好!";             
    s.user = u;                             //  s引用了u   u的计数器变为2
    
    Status *s2 = [[Status alloc] init];     //  s2的计数器是1
    s2.text = @"今天天气真的很好!";
    s2.retweetStatus = s;                   // s2引用了s    s的计数器变为2
    s2.user = u2;                           // s2引用了u2   u2的计数器2 
    
    [u2 release];                           // [u2 release] u2计数器变为1
    [u release];                            // [u release] u计数器变为1
    [s2 release];                           // [u2 release] s2变为0 ;s2引用过的 s.和u2 都减1:u2变为0  u2释放 
    [s release];                            // [s release] s变为0  :u变为0 
    return 0;
}
运行结果:
[3607:303] 用户被释放
[3607:303] 微博被释放
[3607:303] 用户被释放
[3607:303] 微博被释放
Program ended with exit code: 0
@interface Status : NSObject


@property (nonatomic, retain) NSString *text;


@property (nonatomic, retain) NSString *icon;




// 从1970-01-01 00:00:00 开始,一共度过了多少毫秒
@property (nonatomic, assign) long time;
//@property (nonatomic) time_t time;


@property (nonatomic, retain) User *user;


@property (nonatomic, retain) Status *retweetStatus;


@property (nonatomic, assign) int commentsCount;
@property (nonatomic, assign) int retweetsCount;


@end


@implementation Status
- (void)dealloc
{
    [_text release];
    [_user release];
    [_retweetStatus release];
    [_icon release];
    NSLog(@"微博被释放");
    [super dealloc];
}
@end
@implementation User
- (void)dealloc
{
    [_name release];
    [_account release];
    [_icon release];
    [_password release];
    [_phone release];
    NSLog(@"用户被释放");
    [super dealloc];
}
@end
----------------------------------------------------------------------------------------
@property (nonatomic, retain) 类名 *属性名;

-

0 0
原创粉丝点击