内存管理-MRC

2018-07-27  本文已影响18人  紫荆秋雪_文

现在使用OC编写iOS程序不需要考虑创建的对象该什么时候释放,这是因为引入了自动管理内存机制ARC,在自动管理内存机制MRC时期,对象的释放时需要程序员自己来控制的。下面看看在MRC内存管理机制下是怎么管理对象的释放的,因为ARC也是对MRC的管理,这样清楚了MRC下的内存管理机制后,也就了解了ARC下的内存管理机制

OC对象的内存管理

MRC环境 内存管理MRC环境.png

自定义对象的内存管理

#import <Foundation/Foundation.h>

@interface RevanPerson : NSObject

@end

#import "RevanPerson.h"

@implementation RevanPerson


- (void)dealloc {
    NSLog(@"%s", __func__);
    [super dealloc];
}

@end
#import "ViewController.h"
#import "RevanPerson.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}


- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    //创建对象
    RevanPerson *person = [[RevanPerson alloc] init];
    //释放对象
    [person release];
}

@end
2018-07-27 15:32:12.167713+0800 03-RevanPerson[46646:2945558] -[RevanPerson dealloc]

对象拥有一个对象的属性

情景:person对象拥有一辆车

#import <Foundation/Foundation.h>

@interface RevanCar : NSObject
- (void)run;
@end


#import "RevanCar.h"

@implementation RevanCar

- (void)run {
    NSLog(@"%s", __func__);
}

- (void)dealloc {
    NSLog(@"%s", __func__);
    [super dealloc];
}

@end
#import <Foundation/Foundation.h>
#import "RevanCar.h"

@interface RevanPerson : NSObject {
    RevanCar *_car;
}


/**
 给属性_car赋值
 */
- (void)setCar:(RevanCar *)car;

/**
 获取person对象中的_car属性
 */
- (RevanCar *)getCar;

@end

#import "RevanPerson.h"

@implementation RevanPerson

/**
 给属性_car赋值
 */
- (void)setCar:(RevanCar *)car {
    _car = car;
}

/**
 获取person对象中的_car属性
 */
- (RevanCar *)getCar {
    return _car;
}

- (void)dealloc {
    NSLog(@"%s", __func__);
    [super dealloc];
}

@end
#import "ViewController.h"
#import "RevanPerson.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}


- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    //创建对象
    RevanPerson *person = [[RevanPerson alloc] init];//person :1
    //创建一个car
    RevanCar *car1 = [[RevanCar alloc] init];//car1 :1
    
    [person setCar:car1];
    
    [[person getCar] run];
    
    [car1 run];
    //释放对象car1
    [car1 release];//car1 :0
    //释放对象person
    [person release];//person :0
}

@end
2018-07-27 15:45:50.461635+0800 03-RevanPerson[46866:2956657] -[RevanCar run]
2018-07-27 15:45:50.462310+0800 03-RevanPerson[46866:2956657] -[RevanCar dealloc]
2018-07-27 15:45:50.463140+0800 03-RevanPerson[46866:2956657] -[RevanPerson dealloc]

car1对象释放后调用[[person getCar] run]

//
//  ViewController.m
//  03-RevanPerson
//
//  Created by 紫荆秋雪 on 2018/7/27.
//  Copyright © 2018年 紫荆秋雪. All rights reserved.
//

#import "ViewController.h"
#import "RevanPerson.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}


- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    //创建对象
    RevanPerson *person = [[RevanPerson alloc] init];//person :1
    //创建一个car
    RevanCar *car1 = [[RevanCar alloc] init];//car1 :1
    
    [person setCar:car1];
    
    [[person getCar] run];
    
    //释放对象car1
    [car1 release];//car1 :0
    
    
    [[person getCar] run];
    //释放对象person
    [person release];//person :0
}

@end

setCar方法中对car对象进行一次retain操作

#import <Foundation/Foundation.h>
#import "RevanCar.h"

@interface RevanPerson : NSObject {
    RevanCar *_car;
}


/**
 给属性_car赋值
 */
- (void)setCar:(RevanCar *)car;

/**
 获取person对象中的_car属性
 */
- (RevanCar *)getCar;

@end

#import "RevanPerson.h"

@implementation RevanPerson

/**
 给属性_car赋值
 */
- (void)setCar:(RevanCar *)car {
    _car = [car retain];
}

/**
 获取person对象中的_car属性
 */
- (RevanCar *)getCar {
    return _car;
}

- (void)dealloc {
    NSLog(@"%s", __func__);
    [super dealloc];
}
@end
#import "ViewController.h"
#import "RevanPerson.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}


- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    //创建对象
    RevanPerson *person = [[RevanPerson alloc] init];//person :1
    //创建一个car
    RevanCar *car1 = [[RevanCar alloc] init];//car1 :1
    
    [person setCar:car1];//car1 :2
    
    [[person getCar] run];
    
    //释放对象car1
    [car1 release];//car1 :1
    
    [[person getCar] run];
    //释放对象person
    [person release];//person :0
}

@end
2018-07-27 16:09:02.325394+0800 03-RevanPerson[47207:2973778] -[RevanCar run]
2018-07-27 16:09:02.325611+0800 03-RevanPerson[47207:2973778] -[RevanCar run]
2018-07-27 16:09:02.326467+0800 03-RevanPerson[47207:2973778] -[RevanPerson dealloc]
#import "RevanPerson.h"

@implementation RevanPerson

/**
 给属性_car赋值
 */
- (void)setCar:(RevanCar *)car {
    _car = [car retain];
}

/**
 获取person对象中的_car属性
 */
- (RevanCar *)getCar {
    return _car;
}

- (void)dealloc {
    NSLog(@"%s", __func__);
    [_car release];
    [super dealloc];
}

@end
#import "ViewController.h"
#import "RevanPerson.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}


- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    //创建对象
    RevanPerson *person = [[RevanPerson alloc] init];//person :1
    //创建一个car
    RevanCar *car1 = [[RevanCar alloc] init];//car1 :1
    
    [person setCar:car1];//car1 :2
    
    [[person getCar] run];
    
    //释放对象car1
    [car1 release];//car1 :1
    
    [[person getCar] run];
    //释放对象person
    [person release];//person :0
}

@end
2018-07-27 16:19:26.164249+0800 03-RevanPerson[47355:2982538] -[RevanCar run]
2018-07-27 16:19:26.164438+0800 03-RevanPerson[47355:2982538] -[RevanCar run]
2018-07-27 16:19:26.164548+0800 03-RevanPerson[47355:2982538] -[RevanPerson dealloc]
2018-07-27 16:19:26.164885+0800 03-RevanPerson[47355:2982538] -[RevanCar dealloc]

person对象属性对象连续被不同对象赋值时

情景:当person对象中的car属性连续被不同的car对象赋值会怎么样

#import "ViewController.h"
#import "RevanPerson.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}


- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    //创建对象
    RevanPerson *person = [[RevanPerson alloc] init];//person :1
    //创建一个car
    RevanCar *car1 = [[RevanCar alloc] init];//car1 :1
    
    RevanCar *car2 = [[RevanCar alloc] init];//car2 :1
    
    [person setCar:car1];//car1 :2
    [person setCar:car2];//car2 :2
    
    [[person getCar] run];
    
    //释放对象car1
    [car1 release];//car1 :1
    [car2 release];//car1 :1
    
    [[person getCar] run];
    //释放对象person
    [person release];//person :0
}

@end
2018-07-27 16:22:58.699056+0800 03-RevanPerson[47442:2985678] -[RevanCar run]
2018-07-27 16:22:58.699304+0800 03-RevanPerson[47442:2985678] -[RevanCar run]
2018-07-27 16:22:58.699423+0800 03-RevanPerson[47442:2985678] -[RevanPerson dealloc]
2018-07-27 16:22:58.699564+0800 03-RevanPerson[47442:2985678] -[RevanCar dealloc]

为了解决这个内存泄露的问题,可以在set方法中先对_car进行一次release操作,也就是先把就属性对象释放然后再赋值

#import "RevanPerson.h"

@implementation RevanPerson

/**
 给属性_car赋值
 */
- (void)setCar:(RevanCar *)car {
    [_car release];
    _car = [car retain];
}

/**
 获取person对象中的_car属性
 */
- (RevanCar *)getCar {
    return _car;
}

- (void)dealloc {
    NSLog(@"%s", __func__);
    [_car release];
    [super dealloc];
}

@end
#import "ViewController.h"
#import "RevanPerson.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}


- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    //创建对象
    RevanPerson *person = [[RevanPerson alloc] init];//person :1
    //创建一个car
    RevanCar *car1 = [[RevanCar alloc] init];//car1 :1
    
    RevanCar *car2 = [[RevanCar alloc] init];//car2 :1
    
    [person setCar:car1];//car1 :2
    [person setCar:car2];//car2 :2
    
    [[person getCar] run];
    
    //释放对象car1
    [car1 release];//car1 :1
    [car2 release];//car1 :1
    
    [[person getCar] run];
    //释放对象person
    [person release];//person :0
}

@end
2018-07-27 16:33:02.448202+0800 03-RevanPerson[47549:2992057] -[RevanCar run]
2018-07-27 16:33:02.448379+0800 03-RevanPerson[47549:2992057] -[RevanCar dealloc]
2018-07-27 16:33:02.448498+0800 03-RevanPerson[47549:2992057] -[RevanCar run]
2018-07-27 16:33:02.448621+0800 03-RevanPerson[47549:2992057] -[RevanPerson dealloc]
2018-07-27 16:33:02.448725+0800 03-RevanPerson[47549:2992057] -[RevanCar dealloc]

僵尸对象

情景:在[car1 release]方法之后再重新把car1赋值给person对象

#import "ViewController.h"
#import "RevanPerson.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}


- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    //创建对象
    RevanPerson *person = [[RevanPerson alloc] init];//person :1
    //创建一个car
    RevanCar *car1 = [[RevanCar alloc] init];//car1 :1
    
    [person setCar:car1];//car1 :2
    
    //释放对象car1
    [car1 release];//car1 :1
    
    //car1多次赋值给person
    [person setCar:car1];
    [person setCar:car1];
    
    [[person getCar] run];
    //释放对象person
    [person release];//person :0
}

@end

决定僵尸对象崩溃

#import "RevanPerson.h"

@implementation RevanPerson

/**
 给属性_car赋值
 */
- (void)setCar:(RevanCar *)car {
    if (_car != car) {
        [_car release];
        _car = [car retain];
    }
}

/**
 获取person对象中的_car属性
 */
- (RevanCar *)getCar {
    return _car;
}

- (void)dealloc {
    NSLog(@"%s", __func__);
    [_car release];
    _car = nil;
    [super dealloc];
}

@end
#import "ViewController.h"
#import "RevanPerson.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}


- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    //创建对象
    RevanPerson *person = [[RevanPerson alloc] init];//person :1
    //创建一个car
    RevanCar *car1 = [[RevanCar alloc] init];//car1 :1
    
    [person setCar:car1];//car1 :2
    
    //释放对象car1
    [car1 release];//car1 :1
    
    //car1多次赋值给person
    [person setCar:car1];
    [person setCar:car1];
    
    [[person getCar] run];
    //释放对象person
    [person release];//person :0
}

@end
2018-07-27 16:52:04.079668+0800 03-RevanPerson[47837:3006816] -[RevanCar run]
2018-07-27 16:52:04.079846+0800 03-RevanPerson[47837:3006816] -[RevanPerson dealloc]
2018-07-27 16:52:04.079950+0800 03-RevanPerson[47837:3006816] -[RevanCar dealloc]

小结

上一篇下一篇

猜你喜欢

热点阅读