/*
多对象内存管理:
以人拥有车为例涉及到@property底层set方法管理内存的实现
注意:人在换车的时候要进行当前传入的车和人所拥有的车进行判断
*/
/********************************* Person.h文件 *********************************/
#import <Foundation/Foundation.h>
#import "Car.h"
@interface Person : NSObject
{
Car *_car;
}
- (void)setCar:(Car *)car;
- (Car *)car;
@end
/********************************* Person.m文件 *********************************/
#import "Person.h"
@implementation Person
// 为Person类中的_car对象传入Car对象 这样“人就拥有车了”
- (void)setCar:(Car *)car
{
/*
对于这种人不停的更换车的问题,为了更严谨最好将目前人所拥有的车_car和Car类对象car做下判断
如果人目前拥有的车本身就是传入进来的车那么则没有必要对车进行替换,而且从代码角度讲会报错
如果两者不相等才意味着要更换车
*/
if (_car != car ) {
// 如果之前Person已经拥有车了,那么对Person类对象正在使用的车的引用计数减一
// 当然在第一次为Person中的_car传入Car的时候 _car = nil 在OC执行后没有任何响应 后面如果要换新车先把旧车引用计数减一
[_car release];
// 对目前Person正在使用的Car对象的引用计数加一
_car = [car retain];
}
}
- (Car *)car
{
return _car;
}
// Person对象在回收前调用此方法
- (void)dealloc
{
// Person对象被回收 那么将Person类对象拥有的Car对象_car对象也应该被回收
[_car release];
NSLog(@"Person对象被回收了");
[super dealloc];
}
@end
/********************************* Car.h文件 *********************************/
#import <Foundation/Foundation.h>
@interface Car : NSObject
{
int _speed;
}
- (void)setSpeed:(int)speed;
- (int)speed;
@end
/********************************* Car.m文件 *********************************/
#import "Car.h"
@implementation Car
- (void)setSpeed:(int)speed
{
_speed = speed;
}
- (int)speed
{
return _speed;
}
- (void)dealloc
{
NSLog(@"速度为%d的Car对象被回收了",_speed);
[super dealloc];
}
@end
/********************************* main.文件 *************************************/
#import <Foundation/Foundation.h>
#import "Person.h"
#import "Car.h"
int main(int argc, const char * argv[])
{
Person *p = [[Person alloc] init];
Car *car1 = [[Car alloc] init];
car1.speed = 100;
// 人拥有第一辆车car1
[p setCar:car1]; // p.car = car1;
Car *car2 = [[Car alloc] init];
car2.speed = 200;
// 人拥有新的车car2 这一步意味着Person中的_car不再引用car1了 那么执行完这一步必须就必须将car1对象回收 因此在为车人拥有car的时候 先将之前car的引用计数在set方法中减一
[p setCar:car2];
Car *car3 = [[Car alloc] init];
car3.speed = 300;
// 人拥有第三辆车car3
p.car = car3; // card3的计数=2
[car3 release];
p.car = car3; // 这行代码无效 是为了将目前人所拥有的车和给人替换的车进行做判断
[car2 release];
[car1 release];
car1 = nil;
[p release];
p = nil;
return 0;
}