iOS 刚开始学者一个关于内存管理的问题

iOS 码拜 9年前 (2015-11-12) 1053次浏览
先上代码,这个例子是   KenshinCui 高手的。拿来学习使用。
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

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明iOS 刚开始学者一个关于内存管理的问题
喜欢 (0)
[1034331897@qq.com]
分享 (0)