OC-内存管理-常见错误

学习了OC中的内存管理,记录一下内存管理中常见的三个问题:野指针,内存泄露,内存过度释放。

首先,创建一个Person 类,完成属性设置,name ,sex,age  

再设置一个便利构造器类方法,来设置属性值

前提介绍完了,下面看一下常见错误代码:

第一个要介绍的是野指针错误,即指向一个你没有所有权的内存空间,并且该内容空间已经被释放

@autoreleasepool {

        

       Person *person = [PersonpersonWithName:@"jack"sex:@"man"age:22];

        [personsaySelf];

        [personretain];//2

       NSLog(@"%ld",[personretainCount]);

        [personrelease];//1

       NSLog(@"%ld",[personretainCount]);

        [personrelease];//0

       NSLog(@"%ld",[personretainCount]);

        //野指针 *person

        [personsaySelf];

}

前面已经释放了空间,但是指针没有指空,指向的空间是我们不可控制的,所以就会崩溃。

解决办法就是,使指针指空。

@autoreleasepool {

        

       Person *person = [PersonpersonWithName:@"jack"sex:@"man"age:22];

        [personsaySelf];

        [personretain];//2

       NSLog(@"%ld",[personretainCount]);

        [personrelease];//1

       NSLog(@"%ld",[personretainCount]);

        [personrelease];//0

       NSLog(@"%ld",[personretainCount]);

        //野指针 *person

        person =nil;

        [personsaySelf];

}


第二个问题就是内存过度释放问题:

@autoreleasepool {

       Person *person = [PersonpersonWithName:@"jack"sex:@"man"age:22];

        [personsaySelf];

        [personretain];//2

        [personretain];//3

        [personrelease];//2

        [personrelease];//1

        [personrelease];//0

        [personrelease];//过度释放

        [personsaySelf];

}

这个问题比较简单,就是对释放过的内存再次释放,导致崩溃。


第三个问题就是内存泄露,一道面试题,就是内存泄露问题,我们先来看问题代码:

@autoreleasepool

    {

       for (NSInteger i =0; i <100000000000000000; i++)

        {

            

           Person *person = [PersonpersonWithName:@"zhaozhao"               sex:@"girl"age:24];

            [personautorelease];

            

        }

        

        

    }

这道题是道典型的内存泄露问题,每一次申请空间都没有释放,仅仅是放入了自动释放池,这时候每个对象的引用计数器都是1,不是0,不会释放内存,而这个循环的条件很大,内存被申请完了,自动释放池还没有释放,导致了最后内存的泄露。


解决方案:

@autoreleasepool

{

   for (NSInteger i =0; i <100000000000000000; i++)

   {

            

       @autoreleasepool {

       Person *person = [PersonpersonWithName:@"zhaozhao"sex:@"girl" age:24];

                [personautorelease];

        }    //每一次创建都释放,就不会导致内存泄露

    }

}



还有一个问题就是常量区的引用计数无限的,无法被释放。来看一个例子:

@autoreleasepool {

        Person *person = [Person personWithName:@"jeff" sex:@"man" age:24];

         person = @"aaa";//常量区的引用计数为无穷大,无法释放

        [person release];

        NSLog(@"计数器 %ld",[personretainCount]);

}

当我们运行程序的时候会看到输出的引用计数器 为 -1。


接下来的一个问题就是指针的重定向问题引发的内存管理错误。

@autoreleasepool {

        Person *person = [Person personWithName:@"jeff" sex:@"man" age:24];

        person = [[Person allocinit];

       [person release];// 0

        NSLog(@"计数器 %ld",[personretainCount]);

        [person release];//指针重指向新的堆 过度释放

        NSLog(@"计数器 %ld",[personretainCount]);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值