/*
Objective-c - 多个对象的内存管理之二
在<<多个对象的内存管理之:一个对象作为另一个对象的属性>>的基础之上,增加一个新的车对象,然后将新的车对象赋值给人对象,而这样会出现的问题:
当程序结束的时候新车和人会释放,而旧车无法释放,原因是旧车的release消息在人的dealloc方法中.
解决:
为人对象的车属性赋新值的时候,代表旧对象不再使用,新对象多一个人使用,此时,应该先为就对象发送一条release消息,再retain新对象;
代码如下:
- (void)setCar:(YYCar *)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 = [super init])
{
self.brand = brand;
}
return self;
}
+ (instancetype)carWithBrand:(NSString *)brand
{
return [[self alloc] 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
{
[_car release];
_car = [car retain];
}
- (YYCar *)car
{
return _car;
}
- (void)drive:(YYCar *)car
{
NSLog(@"%@开着%@去上学!", [self name], [car brand]);
[car run];
}
//自定义构造方法
- (instancetype)initWithName:(NSString *)name
{
if(self = [super init])
{
self.name = name;
}
return self;
}
- (instancetype)initWithName:(NSString *)name andCar:(YYCar *)car
{
if(self = [super init])
{
self.name = name;
self.car = car;
}
return self;
}
+ (instancetype)personWithName:(NSString *)name;
{
return [[self alloc] initWithName:name];
}
+ (instancetype)personWithName:(NSString *)name andCar:(YYCar *)car
{
return [[self alloc] initWithName:name andCar:car];
}
@end
#pragma mark -
#pragma mark main函数
int main(int argc, const char * argv[]) {
//人对象的创建及初始化
YYPerson *xiaoming = [YYPerson personWithName:@"小明"];
NSLog(@"xiaoming.retainCount = %lu", xiaoming.retainCount);
//奔驰车对象的创建及初始化
YYCar *bz = [YYCar carWithBrand:@"奔驰"];
NSLog(@"bz.retainCount = %lu", bz.retainCount);
//奥迪车对象的创建及初始化
YYCar *ad = [YYCar carWithBrand:@"奥迪"];
//将车对象赋值类人类对象,此时代表车类对象多一个人使用,方法内部为车对象发送了一天retain消息.
xiaoming.car = bz;
[xiaoming drive:bz];
//为人对象的车属性赋新值的时候,代表旧对象不再使用,新对象多一个人使用,此时,应该先为就对象发送一条release消息,再retain新对象;
xiaoming.car = ad;
[xiaoming drive:ad];
[bz release];
[ad release];
//人对象释放的时候,代表车对象少一个人使用,此时dealloc方法内部为车对象匹配了一条release消息.
[xiaoming release];
return 0;
}