黑马程序员****OC语言基础****MRC的理解

本文深入探讨了Java中的内存管理机制,通过实例分析MRC(Manual Reference Counting)原理,展示如何在对象销毁时自动调用dealloc方法,并正确处理多对象引用。以Person和Car类为例,详细阐述了如何在类间传递对象并合理管理引用计数,避免内存泄露,确保程序高效稳定运行。

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

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

       概念:

       MRC:MannulReference Counting ( 手动管理 ) 

         对引用计数器的操作 :
         
retain消息:使计数器+1,该方法返回对象本身

         release消息:使计数器-1(并不代表释放对象)

         retainCount消息:获得对象当前的引用计数器值

         当一个对象的引用计数器为0时,那么它将被销毁,其占用的内存被系统回收。

         当对象被销毁时,系统会自动向对象发送一条dealloc消息,一般会重写dealloc方法,在这里释放相关的资源,dealloc就像是对象的“临终遗言”。

         一旦重写了dealloc方法就必须调用[super dealloc],并且放在代码块的最后调用(不能直接调用dealloc方法)。 

          

        Person.h声明:

       

<span style="font-size:24px;">#import <Foundation/Foundation.h>
@interface Person : NSObject 
@property int age;
@end</span>

        Person.m实现:

<span style="font-size:24px;">#import "Person.h" 
@implementation Person
//重写dealloc方法 
-(void)dealloc{
//释放子类对象
NSLog(@"对象被销毁了~"); 
//释放父类
[super dealloc];
}
@end</span>


        main.m主函数:


<span style="font-size:24px;">#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
    Person *p = [[Person alloc] init];
    NSLog(@"p的retainCount = %ld",p.retainCount);
    Person *p1 = [[Person alloc] init];
    NSLog(@"p1的retainCount = %ld",p1.retainCount);
    [p1 retain];
    NSLog(@"p1的retainCount = %ld",p1.retainCount);
    [p1 release];
    NSLog(@"p1的retainCount = %ld",p1.retainCount);
    [p1 release];   //此时p还没释放,造成内存泄露了
    return 0;
}</span>


          运行结果: p retainCount = 1

           p1retainCount = 1

           p1retainCount = 2

           p1retainCount = 1

           对象被销毁了~


          实例分析:凤姐去拉萨多对象处理

         Person.h声明:

 

<span style="font-size:24px;">#import <Foundation/Foundation.h>
#import "Car.h"
@interface Person : NSObject{
    Car *_car;
}
-(void)dealloc;
-(void)goLasa;
-(void)setCar:(Car *)car;

@end</span>

        Person.m的实现:


<span style="font-size:24px;">#import "Person.h"

@implementation Person
-(void)dealloc{
    [_car release];     //在人对象释放前,先释放掉车的对象
    NSLog(@"人已经挂了!");
    [super dealloc];
}
-(void)goLasa{
   
    [_car run];  //插入车的跑方法
}
/*此处会有一个新的问题:
  如果此时并未出现新的对象,而是旧的对象,如果没有判断的话
  此时旧的对象会变成僵尸对象,程序则会出错。
*/
-(void)setCar:(Car *)car{
    if(_car != car){
    [_car release];       //为了防止车的多对象产生内存泄露,在retain之
                          // 前释放掉当前对象
    _car = [car retain];  //给人的对象设置车时,再次增加一次车的retain

    }
    }
@end</span>

      Car.h声明:


<span style="font-size:24px;">#import <Foundation/Foundation.h>

@interface Car : NSObject/*{
    int _speed;
}*/
@property int speed;
-(void)dealloc;
//-(int)setSpeed:(int)speed;
//-(void)getSpeed;
-(void)run;

@end</span>

      Car.m的实现:


<span style="font-size:24px;">#import "Car.h"

@implementation Car
-(void)dealloc{
    NSLog(@"速度为 %d 码的车已经挂了",_speed);
    [super dealloc];
}
/*-(int)setSpeed:(int)speed{
    _speed = speed;
    return speed;
}
-(void)getSpeed{
    
}*/
-(void)run{
NSLog(@"汽车正以%d码的速度奔向拉萨",_speed);
}

@end</span>

        main.m主函数:


<span style="font-size:24px;">#import <Foundation/Foundation.h>
#import "Car.h"
#import "Person.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *fj = [Person new];//此时fj的retainCount就变成了1;
        Car *bmw = [Car new];//此时bmw的retainCount就变成了1;
       
        [fj setCar:bmw];
       // [bmw setSpeed:100];
        bmw.speed = 200;
        
        [fj goLasa];//在setCar中插入了[_car retain]
        [fj goLasa];//此时bmw的retainCount就变成了2;
        [fj goLasa];
        
        NSLog(@"retainCount = %lu",bmw.retainCount);
        [bmw release];//内存管理原则,谁创建谁release
        
        Car *qq = [Car new];
        [fj setCar:qq];
        [qq setSpeed:20];
       // NSLog(@"retainCount = %lu",bmw.retainCount);
        [fj goLasa];
        [fj goLasa];
        [fj goLasa];
        [qq release];
        [fj release];//内存管理原则,谁创建谁release
       // NSLog(@"retainCount = %lu",bmw.retainCount);
        
    }
    return 0;
}</span>

        运行结果: 汽车正以 200 码的速度奔向拉萨

           汽车正以200码的速度奔向拉萨

           汽车正以200码的速度奔向拉萨

           retainCount = 2

           速度为 200 码的车已经挂了  

           汽车正以20码的速度奔向拉萨

           汽车正以20码的速度奔向拉萨

           汽车正以20码的速度奔向拉萨

           速度为 20 码的车已经挂了

           人已经挂了!

        


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值