先上代码,这个例子是 KenshinCui 高手的。拿来学习使用。
car.h
car.h
#import <Foundation/Foundation.h> @interface Car : NSObject #pragma mark - 属性 #pragma mark 车牌号 @property (nonatomic,copy) NSString *no; #pragma mark - 公共方法 #pragma mark 运行方法 -(void)run; @end
car.m
#import "Car.h" @implementation Car #pragma mark - 公共方法 #pragma mark 运行方法 -(void)run{ NSLog(@"Car(%@) run.",self.no); } #pragma mark - 覆盖方法 #pragma mark 重写dealloc方法 -(void)dealloc{ NSLog(@"Invoke Car(%@) dealloc method.",self.no); [super dealloc]; } @end
person.h
#import <Foundation/Foundation.h> @class Car; @interface Person : NSObject { Car *_car; } #pragma mark - 属性 #pragma mark 姓名 @property (nonatomic,copy) NSString *name; #pragma mark - 公共方法 #pragma mark Car属性的set方法 -(void)setCar:(Car *)car; #pragma mark Car属性的get方法 -(Car *)car; @end
person.m
#import "Person.h" #import "Car.h" @implementation Person #pragma mark - 公共方法 #pragma mark Car属性的set方法 -(void)setCar:(Car *)car{ if (_car!=car) { //首先判断要赋值的变量和当前成员变量是不是同一个变量 // _car = nil; [_car release]; //释放之前的对象 _car=[car retain];//赋值时重新retain } } #pragma mark Car属性的get方法 -(Car *)car{ return _car; } #pragma mark - 覆盖方法 #pragma mark 重写dealloc方法 -(void)dealloc{ NSLog(@"Invoke Person(%@) dealloc method.",self.name); [_car release];//在此释放对象,即使没有赋值过由于空指针也不会出错 [super dealloc]; } @end
main.h
#import <Foundation/Foundation.h> #import "Person.h" #import "Car.h" void getCar(Person *p){ Car *car1=[[Car alloc]init]; car1.no=@"888888"; p.car=car1; NSLog(@"retainCount(p)=%lu",[p retainCount]); Car *car2=[[Car alloc]init]; car2.no=@"666666"; [car1 release]; car1=nil; [car2 release]; car2=nil; } int main(int argc, const char * argv[]) { @autoreleasepool { Person *p=[[Person alloc]init]; p.name=@"Kenshin"; getCar(p); [p.car run]; [p release]; p=nil; } return 0; }
上运行结果:
2015-10-12 22:20:32.089 1010-内存[380:303] retainCount(p)=1
2015-10-12 22:20:32.092 1010-内存[380:303] Invoke Car(666666) dealloc method.
2015-10-12 22:20:32.094 1010-内存[380:303] Car(888888) run.
2015-10-12 22:20:32.095 1010-内存[380:303] Invoke Person(Kenshin) dealloc method.
2015-10-12 22:20:32.096 1010-内存[380:303] Invoke Car(888888) dealloc method.
Program ended with exit code: 0
问题:
再getcar方法中,明明是car1代码先release,为什么却是 Invoke Car(666666) dealloc method. car2先release了。
为什么car1的release代码放到了最后面?
解决方案:40分
原因是 p.car=car1;
car1 调用release之后引用不为0 ,不会真正释放car1,而会等待p释放的时候才释放car1
car1 调用release之后引用不为0 ,不会真正释放car1,而会等待p释放的时候才释放car1