内存管理(1) - 引用计算的基本操作

内存管理

内存管理其实就是对引用计数的管理,需要从MRC和ARC两方面探讨,其中MRC与ARC的主要区别是MRC下需要手动retain、release、autorelease等在ARC下会自动完成。


1、引用计数相关操作
对象操作OC中对应的方法对应的 retainCount 变化
生成并持有对象alloc/new/copy/mutableCopy等+1
持有对象retain+1
释放对象release-1
释放对象dealloc0

alloc

struct objc_layout{
    NSUInteger retained;
};

+(id)alloc
{
    int size = sizeof(struct objc_layout) + 对象大小;
    struct objc_layout *p = (struct objc_layout *)calloc(1, size);
    //1.calloc在动态分配完内存后,自动初始化该内存空间为零,而malloc不初始化,里边数据是随机的垃圾数据。
    //2.struct objc_layout存放引用计数,开辟一个struct objc_layout结构大小加对象大小的内存,并用一个struct objc_layout指针指向该内存。
    return (id) (p+1) ;
    //p是struct objc_layout指针,p+1后指针则指向存放对象的内存
}

retain

+(id)retain
{
    if (((struct objc_layout *)self)[-1].retained == UINT_MAX -  1)
        [NSException raise:NSInternalInconsistencyException format:@"NSIncrementExtraRefCount() asked to increment to far"]; //当retaind变量超出最大值时抛出异常
    ((struct objc_layout *)self)[-1].retained ++;//引用计数加1
}
//这里[-1]其实是拿到对象前面的引用计数的下标
//因为[0]是此对象的下标

release

+ (void)release{
    if (((struct objc_layout *)self)[-1].retained == 0) {
        [self dealloc];  //引用计数为0 释放对象
    }else{
        ((struct objc_layout *)self)[-1].retained--;  //引用计数减1
    }
}     

dealloc

+ (void) dealloc
{
    struct objc_layout *o = &((struct objc_layout *)self)[-1];
    free(o);
}

2、内存管理规则

这里写图片描述


3、几种生成与持有对象的情况
//自己生成对象并持有对象
id obj0 = [[NSObject alloc] init];
id obj1 = [NSObject new];
//自己不生成对象但是持有对象,但是对象存在
id obj0 = [NSArray array]
[obj0 retain]
id obj0 = [[NSObject alloc] init];
id obj1 = [NSObject new];   //生成并持有对象
[obj0 release]   //释放对象
[obj1 release]   //释放对象
id obj0 = [NSArray array]   
//自己不生成对象, 但是对象存在   
[obj0 release]     
//会出错,因为它不持有这个对象,但是又给它发送了release

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值