OC中内存管理之MRC

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

相关知识引入

1)对象所有权:任何对象都可能拥有一个后多个所有者,只要一个对象至少还拥有一个所有者,这个对象就会继续存在。

2)对象的引用计数器:每个OC对象都有自己的引用计数器,是一个整数,表示对象被引用的次数,也就是现在偶多少东西在使用这个对象,对象被创建时,默认引用计数器      是1,当计数器值变成0的时候,则销毁该对象。(对象值为nil时,引用计数器值为0,但不回收空间)

3)引用计数器的操作:

a) retain引用计数器+1

b) release引用计数器-1

c) retainCount获得引用计数器的值

4)一个对象被销毁时,会调用该对象的  dealloc  方法,

a) dealloc 方法是NSObject的方法,我们一般需要重写

b) 重写dealloc方法时,内部一定要调用[super dealloc]

#import "Person.h"

@implementation Person
- (void)dealloc
{
    NSLog(@"重写dealloc方法,释放对象");
    [super dealloc];
}
@end

MRC是手动内存管理,需要人为控制对象的引用计数器来实现对象的释放。

内存管理原则:

1)如果对象有人使用,就不应该回收

2)如果你想使用这个对象,应该让这个对象retain一次

3)如果你不想使用这个对象了,应该让这个对象release一次

4)谁创建,谁release

5)谁retain,谁release

声明和实现一个person类

#import <Foundation/Foundation.h>

@interface Person : NSObject

@end

#import "Person.h"

@implementation Person

//重写父类的dealloc方法
- (void)dealloc
{
    NSLog(@"重写dealloc方法,释放对象");
    [super dealloc];
}
@end

在main方法中实现简单MRC

#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        //创建对象
        Person *person = [Person new];
        NSLog(@"%lu",[person retainCount]); //引用计数器=1
        //
        Person *p =[person retain];
        NSLog(@"%lu",[person retainCount]); //person的引用计数器=2
        NSLog(@"%lu",[p retainCount]);      //p的引用计数器=2

        //person   retain的,所以person    release
        [person release];
        NSLog(@"%lu",[person retainCount]); //person的引用计数器=1
        NSLog(@"%lu",[p retainCount]);      //p的引用计数器=1
        
        //用person 创建的对象,所以person  release
        //因为此时的引用计数器为1,执行完下面的release后,引用计数器为0,所以调用对象的dealloc方法
        [person release];//重写dealloc方法,释放对象
    }
    return 0;
}

MRC在多对象时的应用(通过set方法实现内存的管理)

创建两个类 ,person 和 car

#import <Foundation/Foundation.h>

@interface Car : NSObject

@end


在Car.m文件中实现父类NSObject的dealloc方法
#import "Car.h"

@implementation Car

- (void)dealloc
{
    NSLog(@"car重写父类的dealloc方法,车被释放");
    [super dealloc];
}
@end


Car作为Person类的一个成员变量,声明set方法
@class Car;
@interface Person : NSObject
{
    Car *_car;

}
-(void)setCar:(Car *)car;
@end


在Person.m文件中,实现set方法,

1)判断赋值前后的新值和旧值是否相等,如果相等则不做任何操作。

2)如果不等则  release旧值,retain新值并赋值

#import "Person.h"
#import "Car.h"
@implementation Person

-(void)setCar:(Car *)car{

    //判断新值和旧值是否相等
    if (_car != car) {
        
        //release旧值
        [_car release];
        
        //retain新值
        _car = [car retain];
    }

}

//重写父类的dealloc方法
- (void)dealloc
{
    //释放成员变量
    [_car release];
    NSLog(@"person重写dealloc方法,释放对象");
    //释放父类空间
    [super dealloc];
}
@end

main函数中得应用

#import <Foundation/Foundation.h>
#import "Person.h"
#import "Car.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        //创建独对象
        Person *p = [Person new];
        Car *c =[Car new];
        NSLog(@"\n%lu\t%lu",[p retainCount],[c retainCount]);//对象创建后默认计数器是1  结果:1	1
        
        //调用person的setCar方法,给person的_car赋值
        [p setCar:c];
        
        //在setCar方法中,判断两值不等,此时旧值为nil,新值是c,所以[nil release],[c retain]
        NSLog(@"\n%lu\t%lu",[p retainCount],[c retainCount]);//结果:1	2
        
        //创建第二辆车
        Car *c1 = [Car new];
        
        //把c1赋值给persong 的_car,此时旧值为c,新值为c1,所以[c release],[c1 retain]
        [p setCar:c1];
        NSLog(@"\n%lu\t%lu\t%lu",[p retainCount],[c retainCount],[c1 retainCount]);//结果:1	1	2
        
        //p创建,p    release,p调用dealloc方法时,执行[_car release] 此时的_car是c1,也就是[c1 release]
        [p release];//person重写dealloc方法,释放对象,
        
        //c创建,c    release
        [c release];//car重写父类的dealloc方法,车被释放
        
        //c1创建,c1    release
        [c1 release];//car重写父类的dealloc方法,车被释放
        
    }
    return 0;
}





















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值