OC中的内存管理及MRC和ARC单个对象的内存管理问题

本文详细探讨了Objective-C中的内存管理机制,包括手动管理(MRC)和自动管理(ARC),并通过实例展示了单个对象在不同管理模式下的行为差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、

   1.内存分区图:高地址  栈 区:局部变量                   代码块结束时,系统自动释放,不需要进行管理

                                           堆 区:创建的对象                 而在堆区中创建的对象不会自动释放,需要我们进行管理

 

                                           BSS段:未初始化的全局变量和静态变量  ]

                                          数据段:初始化的全局变量和静态变量      ]此三项程序启动时,自动加载

                            低地址  代码段:代码                                                  ]

   2.OC的内存管理对象是任何继承自NSObject的类的对象,对基本数据类型无效。

   3.OC的内存管理分类:MRC(MannulReference Counting)    手动管理

                                           ARC(AutomaticReference Counting) 自动管理

 二、MRC和ARC下单个对象的内存管理问题

    1.首先我们来看MRC下单个对象的内存管理:野指针和僵尸对象

      建一个类,并把所在的target设置为MRC

    #import <Foundation/Foundation.h>

    @interface Person:NSObject

    -(void)run;//声明run方法

    @end

    @implementation Person

    -(void)dealloc{//重写dealloc方法

    NSLog(@"Life is over");

    [super dealloc];//调用dealloc方法

    }

    -(void)run{

    NSLog(@"Person is running");//实现run方法

    }

    @end

    int main()

    {

    @autoreleasepool {

    Person *person=[[Person alloc]init];//创建一个对象person,此时其引用计数器为1

    [person release];

    [person run];

 按照内存管理的原则之一,谁创建谁release,把person释放,此时运用计数器为0。此时调用run方法打印出了结果,按理说会报错,因为对象已经不存在了。但没有报错,打开僵尸检测,确确实实报错了。此时,person就是一个野指针,指向了一块对象已经被释放的内存空间及僵尸对象。僵尸对象的管理,是在对象release以后,把指针赋值为nil

    }

    return 0;

    }

 2.ARC下单个对象的内存管理问题:主要分析的是对象在强指针和弱指针引用时的释放情况

   建一个学生类,此时所创建的target默认的便是ARC

  #import <Foundation/Foundation.h>

  @interface Student:NSObject

  @property(nonatomic,copy)NSString *name;

  -(instancetype)initWithName:(NSString *)name;

  @end

  @implementation Student

  -(instancetype)initWithName:(NSString *)name{

  if (self=[super init]) {

  self.name=name;

  }

  return self;

  }

 

  -(void)dealloc{

  NSLog(@"%@ is over",_name);//能重写dealloc,但不能调用[super dealloc]

  }

  @end

  int main(){

  @autoreleasepool {

  __strong Student *student=[[Student alloc]initWithName:@"1"];

  //此时,不能写retain、release和autorelease,对象也会释放。而判断对象是否释放的唯一标准就是有无强指针指向

  //什么都不加时,默认的是强指针指向 例: Student *student=[Student new];

 // 运行结果

 // 2016-01-24 15:08:57.077 博客[628:15156] 1 free

 // 2016-01-24 15:08:57.078 博客[628:15156] 2 is over

 // 2016-01-24 15:08:57.078 博客[628:15156] (null) free

 // 2016-01-24 15:08:57.079 博客[628:15156] 1 is over

 // Program ended with exit code: 0

 

 //运行可以看出2早于1先被释放,因为被强指针指向的对象会在@autorelease所在的花括号结束时释放,而被弱指针指向的对象在声明完成后立即释放

 NSLog(@"%@ free",student.name);

 __weak Student *student1=[[Student alloc]initWithName:@"2"];//声明完成后立即释放

 NSLog(@"%@ free",student1.name);

 }

 return 0;

 }

本人个人见解,可能仍有些情况没有考虑到,欢迎大家批评指正
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值