OC 第四讲 内存管理机制,引用计数

iOS 应用程序中会出现crash ,90%以上原因是内存问题。

了解内存问题并掌握内存管理的机制,就能减少出错几率,提高程序性能,大大减少调试时间。

常见内存问题:内存溢出,野指针异常。

首先,我们建立1个类:

import <Foundation/Foundation.h>

@interface Person : NSObject  <NSCopying>

{

NSString *_name;

}

///  初始化方法

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

///  便利构造器

+ (id)personWithName:(NSString *)name;



实现部分:

#import "Person.h"

- (id)initWithName: (NSString *)name

{

self = [super init];

if (self) {

_name = name;

}

return self;

}


///  便利构造器

+ (id)personWithName:(NSString *)name

{

    Person *p = [[[Person alloc] initWithName:name] autorelease]; //自动释放

    return p;

}


///  实现协议copy的方法

- (id)copyWithZone:(NSZone *)zone

{

    Person *p = [[Person allocWithZone:zone]

                 initWithName:[NSString stringWithFormat:@"%@的克隆人", _name]];

    return p;

}


///  重写父类的dealloc方法

- (void)dealloc      //验证对象引用计数是否为0

{

    

    NSLog(@"%@%@对象被销毁了", self, _name);

    //对成员变量释放

//    [_name release];

//    _name = nil;

    [super dealloc];

}



@end




main.m

        Person *jingGeGe = [[Person alloc] initWithName:@"靖哥哥"];//1  //开辟内存空间,引用计数由01

        NSLog(@"%p", &jingGeGe);                      //栈的地址

        NSLog(@"jingGeGe: %p", jingGeGe);             //堆的地址

        NSLog(@"%ld", [jingGeGe retainCount]);        //引用计数变为1

        

        Person *dongJing = [jingGeGe retain];//2      //主张对象持有权,引用计数累加1

        NSLog(@"%ld", [dongJing retainCount]);        //引用计数变为2

        NSLog(@"dongJing: %p", dongJing);

        

        [dongJing release];                           //释放对象,不再持有,引用计数未来减一

        NSLog(@"%ld", [jingGeGe retainCount]);        //引用计数变为1

        NSLog(@"%ld", [dongJing retainCount]);        //不是内存被回收,还可以用

        dongJing = nil;        //对象为空

        [dongJing release];    //[nil release] 向一个空对象发送任何消息,不会产生任何效果,不会报错,不会crash

        NSLog(@"%ld", [dongJing retainCount]);        //对象赋予nil 时,计数输出为0

        

        [jingGeGe release];                           //引用计数变为0;全部被回收

        NSLog(@"%ld", [jingGeGe retainCount]);        //输出计数还是1

//        [jingGeGe release];                         //野指针,crash

/*

  野指针异常主要成因:
  一、指针变量没有被初始化
  二、对象的内存空间已经被回收,仍然使用指针操作这块内存

*/

    

        //  (自动释放)autorelease的好处与习惯用法

        Person *laoWang = [[Person alloc] initWithName:@"隔壁老王"];       //1

//        [laoWang retain];                              //2,引用计数加1,变为2. 不写就会被销毁!写了还剩1.

        [laoWang autorelease];

        NSLog(@"%ld", [laoWang retainCount]);          //2



OC采用引用计数(retain count)记录某块内存持有者的个数。当对象的内存多了一个持有者,引用计数器就递增,少了一个所有者,引用计数就递减。当引用计数到零时,该对象就将释放占有的资源。

+ alloc //开辟内存空间,引用计数由0变1;

-  retain //主张对象持有权,引用计数累加1;

- release //释放对象,不再持有,引用计数减1;

- autorelease // 自动释放对象,引用计数未来减1;

- copy // 拷贝创建一个对象,原有对象引用计数不变。



内存管理原则:

You own any object you create by allocating memory for it or copying it.Related methods: alloc, allocWithZone:, copy, copyWithZone:, mutableCopy, mutableCopyWithZone:

If you are not the creator of an object, but want to ensure it stays in memory for you to use, you can express an ownership interest in it. Related method: retain

If you own an object, either by creating it or expressing an ownership interest, you are responsible for releasing it when you no longer need it.Related methods: release, autorelease

Conversely, if you are not the creator of an object and have not expressed an ownership interest, you must not release it.


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值