单个对象内存管理分析

手动内存管理,主要需要注意2个问题,一个是空指针,另外一个是内存泄露,在开发当中,该如何去避免这样的问题.

  • 首先还是要遵守内存管理原则(配对原则):只要出现了 new,alloc,retain,就一定配对出现一个release,autorelease

    通过代码进行说明:

#import <Foundation/Foundation.h>
#import "Person.h"

void test()//空指针类型
{
    //初始化对象,当前的引用计数器数量为1
    Person * p = [[Person alloc] init];
    p.age = 10;
    NSLog(@"%@",p);
    //执行release操作,对象P的引用计数器减为0,执行Person-->dealloc方法,p被销毁
    [p release];
    //这个时候,对象p已经在内存中被销毁,已经不存在,再通过该对象去调用该类说持有的方法,会引起程序崩溃,这就是一个空指针类型
    [p run];

}

void test2()//针对上面这种空指针情况的处理
{
    Person * p = [[Person alloc] init];//创建一个p对象
    p.age = 20;//执行p的age属性的set方法
    NSLog(@"%@",p);
    //对p的引用计数器减1
    [p release];
    //如果确定当前作用域中的对象已经不会再被使用了,为了防止空指针操作,通常我们会把不在使用的指针变量赋值为nil
    p = nil;
    p.age = 30;//[nil setAge:30];
    [p run]; //[nil run];
    //避免野指针操作的方法 [nil resele]
    //通过这种方法,可以让在运行时保证程序不会崩溃
}
void test3()//内存泄漏
{    
     //当前对象p的引用计数器值为1
     Person * p = [[Person alloc] init];
     p.age = 20;
     NSLog(@"%@",p);
     //执行retain操作,引用计数器值+1,当前retainCount值为2
     [p retain];

     //执行retain操作,引用计数器值+1,当前retainCount值为3
     [p retain];

     //执行release操作,引用计数器值-1,当前retainCount值为2
     [p release];

     //只要对象的retainCount != 0 就会一直存在在内存中
     //内存泄漏指的就是,不再被使用的对象,一直在内存中没有被销毁
     */

    #if 0
     //内存泄漏另外一种情况
     //retainCount = 1
     Person * p = [[Person alloc] init];
     p.age = 20;
     [p run];
     p = nil;
     [p release];//这种情况同样会导致内存泄露,等同于[nil release]
     #endif

    #if 0
    Person * p = [[Person alloc] init];
    p.age = 20;
    [p run];
    Person * p1 = p;//将p所持有的对象让p1也持有,但是不让不执行retain操作,这是p1和p说持有的对象的计数器为1

    //        [p release];
    [p1 release];
    //当通过p或者p1对该对象进行一次release操作的时候,该对象的引用计数器减为0 ,对象销毁,p和p1不再指向任何的对象

    //空指针操作
    p1.age = 20;
#end if
}
void test4()
{
    Person * p = [[Person alloc] init];
    p.age = 20;
    NSLog(@"%@",p);
    [p release];
    //空指针操作,当一个对象retainCount已经为0 时,调用retain方法,是不会使得对象起死回生的,同时还会发生野指针操作异常
    [p retain];
}

void test5(Person * p)
{
    p.age = 30;// release retain
    [p retain]; //2
//    [p release];
    NSLog(@"%@",p);
}

int main(int argc, const char * argv[])
{

    @autoreleasepool {

        //1
        Person * p = [[Person alloc] init];
        p.age = 20;
        //将对象作为参数传递到方法里面,参数的引用计数器值不变
        test5(p);
        //1
        [p release];
        //0
        //[p release];

    }
    return 0;
}
#import <Foundation/Foundation.h>

@interface Person : NSObject

@property int age;
- (void)run;
@end
#import "Person.h"

@implementation Person

- (void)dealloc
{
    [super dealloc];
    NSLog(@"Person 被销毁了");
}

- (NSString *)description
{
    return [NSString stringWithFormat:@"age = %d",_age];
}
- (void)run
{
    NSLog(@"人跑起来了");
}

@end
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值