OC的内存管理

内存管理的方式有三种:1.垃圾回收 2.MRC手动:引用计数的方法 3.ARC自动

内存管理的原则就是加减平衡

默认是ARC,调成MRC的方法是:在xcode中,搜索auto,找到ARC选项改成NO.引用计数retainCount在ARC下不能使用,只能在MRC下使用,而且retainCount的作用就是用来显示当前对象的引用情况,是一个参考值

改变引用计数的方法,一共六种

1.retain:就是对引用计数起+1的作用

//    [stu retain];
//    NSLog(@"%ld", [stu retainCount]);
//    [stu retain];
//    [stu retain];
//    [stu retain];
//    NSLog(@"%ld", [stu retainCount]); // 加上创建对象,现在的结果是5
2.release:就是对引用计数进行-1的作用,不是释放!!

//    [stu release];
//    NSLog(@"%ld", [stu retainCount]);
//    [stu release];
//    [stu release];
//    [stu release];
//    NSLog(@"%ld", [stu retainCount]); // 结果是1
3.alloc:也可以改变引用计数,只要对象创建出来,他的引用计数就是1,也相当于能增加引用计数

//    Student *stu = [[Student alloc] init];
//    // 对象的引用计数 retainCount
//    NSLog(@"%ld", stu.retainCount);
4.dealloc:当对象的引用计数加和减平衡之后,该对象就要被释放了,自动调用dealloc进行对象的释放,dealloc才是释放的方法

- (void)dealloc{
    NSLog(@"我被释放了");
    [_name release];
    [_arr release];
    [_dic release];
    [super dealloc];
    // [super dealloc]必须写在最后一位
}
// dealloc是对象最后走的一个方法,在mrc下这个方法里主要写属性的释放
注意: 对象通过alloc进行对象的创建,并且把引用计数+1,然后通过retain和release修改引用计数,当加和减平衡时,自动调用dealloc进行对象的释放.其中alloc和dealloc功能相对,alloc和dealloc功能相对

常见的内存问题:

1.过度释放:当对象已经释放之后再对对象进行relea操作,会引起对象的过度释放,过度释放是以后常见的内存问题

2.野指针:当对象已经释放掉的时候,指针还保存着对象的地址,如果对这个对象继续操作,在UI里马上回崩溃.这种已经释放掉的对象称为野指针,野指针也是非常常见的内存问题

UI里对内存的要求更为苛刻,会直接崩溃,如果是内存问题造成的崩溃,在控制台会显示(lldb),就要找release

5.autorelease:延迟释放对象

autorelease和pool配合使用,只要对象进行autorelease的操作,系统就会把对象添加到自动释放池中,在池子范围内,对象不会改变引用计数,只要超出了池子范围,对象引用计数-1.autorelease会延迟释放对象,release会马上对引用计数进行修改

//    // 自动释放池
//    @autoreleasepool {
//        [stu autorelease];
//        NSLog(@"%ld", [stu retainCount]);
//
//    }
//    NSLog(@"%ld", [stu retainCount]);
什么时候需要写release:如果对象是我们用alloc创建的,需要写release.如果通过便利构造器创建的,不要写release;如果有retain就写release.系统类优先使用便利构造器和字面量,因为不需要内存管理.以后类里面有便利构造器,优先用,因为不需要对内存进行处理,用就好了

6.copy:需要<NSCopying>协议

//    NSString *str = @"马云";
//    NSString *newStr = [str copy];
//    NSLog(@"%@", newStr);
    
//    Student *stu = [Student studentWithName:@"afg" sex:@"m"];
//    Student *newStu = [stu copy];
//    NSLog(@"%@", newStu.name);
//    NSLog(@"%ld", [newStu retainCount]);// 结果是1
//    [newStu release];// 将新的字符串释放<pre name="code" class="objc">- (id)copyWithZone:(NSZone *)zone{
    Student *stu = [Student allocWithZone:zone];
    stu.name = self.name;
    stu.sex = self.sex;
    return stu;
} // copy方法的声明

容器对内存的影响:对象加入到容器里,为了防止对象的野指针问题,会自动给对象的引用计数+1,对象会随着数组消失而消失,或者可变数组移除对象,也可以减少对象的引用计数

//    Student *stu = [[Student alloc] initWithName:@"张丹" sex:@"女"];
//    NSLog(@"%ld", [stu retainCount]);
//    NSArray *arr = @[stu];
//    NSLog(@"%ld", [stu retainCount]); //这个时候结果是2
//    [stu release];
内存与属性:copy(只用NSString使用,copy方法),retain(属性中写retain,那么setter方法可以直接使用), assign(在栈区不需要处理内存)

// set方法主要是为了防止野指针的发生
// 先对传过来的地址和成员变量的地址进行判断,看是不是同一个对象,如果是同一个对象,不做任何的操作
// 如果不是,则把成员变量之前保存的对象先-1,然后对新的值+1,把新的对象付给成员变量保存
//- (void)setPer:(Person *)per{
    // 如果在属性中写了retain,那么setter方法可以直接使用
    // 苹果的官方版:老值比较多,官方版比较好
//    if (_per != per) {
//        [_per release];
//        _per = [per retain]; // 防止野指针
//    }
    
    // 另一个版本:两个版本都可以用,新值比较多,这个比较好
//    [_per release];
//    [per retain];
//    _per = per;

//}









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值