Object-C 内存管理

 

原文学习记录来自:文顶顶博客园

 

一、内存管理基本原理

1、管理范围: 

      任何继承NSObject的对象 (对其他的基本数据类型无效)

      本质原因

  •     对象和其他数据类型在系统中的存储空间不一样(其他局部变量主要存储于栈中,而对象存储于堆中
  •     当代码块结束时这个代码块中涉及的所有局部变量会被回收,指向对象的指针也被回收,此时对象已经没有指针指向,但依然存在与内存中,造成内存泄漏。

2、引用计数器

     (1)是判断对象要不要回收的唯一依据-----引用计数器是否为0(0则销毁,反之则对象不销毁

     (2)引用计数器 通过 retain copy alloc new等方法 使对象的引用计数器+1

     (3)每个对象都有自己的引用计数器(对象被创建时,引用计数器值默认为1

     (4)早每个OC对象内部,都专门有4 个字符的存储空间来存储引用计数器

3、对象的销毁

     (1)当对象的引用计数器为0时,对象会被销毁,其占用的内存会被系统回收

      (2)对象被销毁时,系统会自动想对象发送一条dealloc消息,一般会重写dealloc方法,在这里释放相关的资源。

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

       (3)一旦对象被回收了,那么他所占据的存储空间就不再可用,坚持使用会导致程序崩溃(野指针错误)。

 

4、相关概念和使用注意

        (1) 野指针错误:访问了一块坏的内存(已经被回收,不可用的内存)

        (2)僵尸对象:所占内存已经被回收的对象,僵尸对象不能再被使用。(解决:打开僵尸对象检测)

        (3)空指针:没有指向任何东西的指针(存储的东西是null ,nil,0),给空指针发送消息不会报错

         注不能使用[p retain]让僵尸对象起死复生

 

二、内存管理原则

       谁创建(retain /copy / alloc / new)    谁释放(release / autrelease) 

三、内存管理代码规范

       (一)Set方法的代码规范

           1、基本类型,直接复制

-(void)setAge:(int )age{

    _age = age;
}

          2、对象类型

-(void)setCar : (Car *)car {

     if(_car != car)  // 判断是不是新传进来的对象
     {

         [_car release];   // 对旧对象做一次release  若没有旧对象则没影响

         _car = [car retain];   //  对新对象做一次retain

      }
}

       (二)Deallco方法的代码规范

             (1)一定要[super dealloc],而且要放到最后

             (2)对self(当前)所拥有的其他对象做一次release操作     

-(void)dealloc {

      [_car release];
   

      [super dealloc];
}

四、内存管理中的循环引用问题以及解决

例:每个人有一张身份证,每张身份证对应一个人,不能使用#import方式相互包含,这就形成了循环引用。

1、关键字 @class  类名;------- 来解决循环引用问题,提高性能。

     (1)@class关键字作用

     @class 仅仅告诉编译器,在进行编译的时候把后面的名字作为一个类来处理

     @class 作用----- 声明一个类,告诉编辑器某个名称是一个类

     @class 开发中引用一个类的规范

     (2)使用方法

        在 .h文件中使用@class来声明类    在.m文件中真正使用到的时候,使用#import来包含类中的所有东西

2、两端循环引用的解决方法

     一端使用retain,一端使用assign(使用assign的dealloc中也不再release)

 

五、Autorelease使用

1、基本用法

  •  会将对象放到一个自动释放迟中
  • 当自动释放池被销毁时,会对池子里的所有对象做一次release
  • 会返回对象本身
  • 调用完auto release方法后,对象的计数器不受影响(销毁时影响)

2、好处

  • 不需要再关心对象的释放时间
  • 不需要再关心什么时候调用release

3、使用注意

  • 占用内存较大的对象,不要随便使用autorelease,应该使用release来精确控制
  • 占用内存较小的对象使用autorelease,没有太大的影响

4、错误写法

  • 连续调用多次Autorelease,释放池销毁时执行两次release
  • Alloc之后调用了Autorelease,之后又调用了release

5、自动释放池

  • 在iOS运行过程中,会创建无数个池子,这些池子都是以栈结构(先进后出)存在的
  • 当一个对象调用autorelease时,会将这个对象放到栈顶的释放池中

6、自动释放池的创建方式

  • iOS5.0以前的创建方式 
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

     ......

[pool release]; // [pool drain];用于Mac 

ios5以后

autorelease
{ // 开始代表创建自动释放池

。。。。。。

}// 结束表示销毁自动释放池

7、Autorelease注意

  • 系统自带的方法中,如果不包含alloc new copy等,则这些方法返回的对象都是autorelease的,如[NSDate date];
  • 开发中经常会写一些类方法来快速创建一个autorelease 对象,创建对象时不要直接使用类名,而是使用self

 

五、ARC内存管理机制

(一)ARC的判断标准

              只要没有强指针指向对象,对象就会被释放。

(二)指针分类

  • 强指针:默认的情况下,所有的指针都是强指针,关键字是strong

  • 弱指针:_weak关键字修饰的指针  

// 声明一个弱指针如下   

__weak Person *p;

      ARC中,只要弱指针指向的对象不在了,就直接把弱指针做清空操作。

// 不合理,对象一创建出来就被释放掉,对象释放掉后,ARC把指针自动清零

__weak Person *p = [[Person alloc] init];   
  • ARC中的property处不在使用retain,而是使用strong,在dealloc中不需要再[super dealloc];
// 意味着生成的成员变量_dog是一个强指针,相当于以前的retain

@property (nonatomic , strong) Dog *dog;
  • 如果指针是弱指针,则换成weak,不需要加__;

(三)ARC的特点总结

  1. 不允许调用release、retain、retainCount(获取当前对象的引用计数器数)
  2. 允许重写dealloc,但是不允许调用[super dealloc]
  3. @property的参数 
  •   Strong: 相当于原来的retain(适用于OC对象),成员变量是强指针
  •   Weak:   相当于原来的assign(适用于OC对象),成员变量是弱指针
  •   assign: 适用于非OC对象类型(基础类型)

(四)补充

  1. 程序兼容ARC 和 非ARC 部分 
  • 转变为非ARC -fno-objc-arc 
  • 转变为ARC  -f-objc-ar
  •  
  •  
  • ARC循环引用问题:一端使用Strong,另一端使用assign

 

  •  
  •  
  • 提示:字符串是特殊的对象,但不需要使用release手动释放,这种字符串对象默认就是autorelease的,不用额外的去管理内存         

 

 

目录

 

一、内存管理基本原理

1、管理范围: 

2、引用计数器

3、对象的销毁

4、相关概念和使用注意

二、内存管理原则

三、内存管理代码规范

       (一)Set方法的代码规范

       (二)Deallco方法的代码规范

四、内存管理中的循环引用问题以及解决

五、Autorelease使用

1、基本用法

2、好处

3、使用注意

4、错误写法

5、自动释放池

6、自动释放池的创建方式

7、Autorelease注意

五、ARC内存管理机制

(一)ARC的判断标准

(二)指针分类

(三)ARC的特点总结

(四)补充

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值