Objective-c - 多个对象的内存管理之三:为某个属性反复赋值同一个对象

来源:互联网 发布:中智软件开发有限公司 编辑:程序博客网 时间:2024/06/06 02:23

/*

 Objective-c - 多个对象的内存管理之三:如果对某个属性反复赋值的是同一个对象,不应该反复的release旧的,retain新的.

 当我们多次为属性赋值相同的对象的时候,就会出现僵尸对象错误.

 

    解决:

        - (void)setCar:(YYCar *)car

         {

            if(_car != car)

         {

            [_car release];

            _car = [car retain];

         }

 

         }

         

        - (void)dealloc

         {

            [_car release];

            [super dealloc];

         }

 

 

 

 

 */

//前提是:关闭ARC,MRC模式下.模拟//小明开车去上学.

#import <Foundation/Foundation.h>


#pragma mark -

#pragma mark 车类的创建

//声明

@interface YYCar : NSObject

{

    NSString *_brand;

}


- (void)setBrand:(NSString *)brand;

- (NSString *)brand;


- (void)run;


//自定义构造方法

- (instancetype)initWithBrand:(NSString *)brand;

+ (instancetype)carWithBrand:(NSString *)brand;


@end


//实现

@implementation YYCar


//重写dealloc方法以监视对象的释放

- (void)dealloc

{

    NSLog(@"%@释放了!",_brand);

    [super dealloc];

}


- (void)setBrand:(NSString *)brand

{

    _brand = brand;

}

- (NSString *)brand

{

    return _brand;

}


- (void)run

{

    NSLog(@"%@在行驶!",_brand);

}


//自定义构造方法

- (instancetype)initWithBrand:(NSString *)brand

{

    if(self = [superinit])

    {

        self.brand = brand;

    }

    return self;

}

+ (instancetype)carWithBrand:(NSString *)brand

{

    return [[selfalloc] initWithBrand:brand];

}


@end


#pragma mark -

#pragma mark 人类的创建

//声明

@interface YYPerson : NSObject

{

    NSString *_name;

    YYCar *_car;

}


- (void)setName:(NSString *)name;

- (NSString *)name;


- (void)setCar:(YYCar *)car;

- (YYCar *)car;


- (void)drive:(YYCar *)car;


//自定义构造方法

- (instancetype)initWithName:(NSString *)name;

- (instancetype)initWithName:(NSString *)name andCar:(YYCar *)car;


+ (instancetype)personWithName:(NSString *)name;

+ (instancetype)personWithName:(NSString *)name andCar:(YYCar *)car;


@end


//实现

@implementation YYPerson


//重写dealloc方法以监视对象的释放

- (void)dealloc

{

    NSLog(@"%@释放了!",_name);

    //人类对象释放的时候,就代表_car指向的对象不再使用了;

    //不再使用一个对象的时候,应该为其发送一条release消息进行匹配.

    [_car release];

    [super dealloc];

}


- (void)setName:(NSString *)name

{

    _name = name;

}

- (NSString *)name

{

    return _name;

}


//car对象赋值给人对象的_car属性,代表car对象多了一个人使用,所以应该为传入的car对象发送一条retain消息,代表多一个人使用;

//为人对象的车属性赋新值的时候,代表旧对象不再使用,新对象多一个人使用,此时,应该先为就对象发送一条release消息,retain新对象;

- (void)setCar:(YYCar *)car

{

    //如果对某个属性反复赋值的是同一个对象,不应该反复的release旧的,retain新的.

    if(_car != car)

    {

        [_car release];

        _car = [car retain];

    }

}

- (YYCar *)car

{

    return _car;

}


- (void)drive:(YYCar *)car

{

    NSLog(@"%@开着%@去上学!", [self name], [carbrand]);

    [car run];

}


//自定义构造方法

- (instancetype)initWithName:(NSString *)name

{

    if(self = [superinit])

    {

        self.name = name;

    }

    return self;

}

- (instancetype)initWithName:(NSString *)name andCar:(YYCar *)car

{

    if(self = [superinit])

    {

        self.name = name;

        self.car = car;

    }

    return self;

}


+ (instancetype)personWithName:(NSString *)name;

{

    return [[selfalloc] initWithName:name];

}

+ (instancetype)personWithName:(NSString *)name andCar:(YYCar *)car

{

    return [[selfalloc] initWithName:nameandCar:car];

}


@end


#pragma mark -

#pragma mark main函数

int main(int argc,const char * argv[]) {

    

    //人对象的创建及初始化

    YYPerson *xiaoming = [YYPersonpersonWithName:@"小明"];

    NSLog(@"xiaoming.retainCount = %lu", xiaoming.retainCount);

    

    

    //奔驰车对象的创建及初始化

    YYCar *bz = [YYCarcarWithBrand:@"奔驰"];

    NSLog(@"bz.retainCount = %lu", bz.retainCount);

    

    

    

    

    

    //将车对象赋值类人类对象,此时代表车类对象多一个人使用,方法内部为车对象发送了一天retain消息.

    xiaoming.car = bz;

    [xiaoming drive:bz];

    

    bz.brand = @"犇迪";

    //当我们多次为属性赋值相同的对象的时候,就会出现僵尸对象错误.

    //所以如果对某个属性反复赋值的是同一个对象,不应该反复的release旧的,retain新的.

    xiaoming.car = bz;

    

    [xiaoming drive:bz];

    

    [bz release];

    //人对象释放的时候,代表车对象少一个人使用,此时dealloc方法内部为车对象匹配了一条release消息.

    [xiaoming release];

    

    return 0;

}

0 0
原创粉丝点击