内存管理小结1

每个对象都有自己的引用计数器

每一个引用计数都占4个字节存放自己的引用计数器

当计数器为0的时候就会回收,对象刚建立的时候计数器数值为1

计数器的操作:

1:给对象发送一条retain消息,可以使引用计数器数值+1(retain方法返回对象本身)

2:给对象发送一条release消息,可以使计数器数值-1

3:可以给对象发送retainCount消息获得当前的引用计数器数值

对象的销毁:

1:当计数器为0 的时候,那么它将被销毁,其占用的内存被系统回收。

2:当对象被销毁时,系统会自动向对象发送一条- dealloc消息

3:一般会重写- dealloc方法,在这里释放相关资源,- dealloc就像是对象的遗言

4:一旦重写了- dealloc方法就必须调用[super dealloc]并且放在最后面调用

5:不要直接调用dealloc方法

6:一旦对象被系统回收,它占用的内存就不可在用,坚持食用会造成系统崩溃(野指针错误)

这些方法都是对象方法。

野指针:指向僵尸对象或者(不可用内存)的指针

//错误提示:EXC-BAD-ACCESS:访问了一块坏内存(已经被回收,不可用的内存)也称为野指针错误

 当计数器为0之后要将指针指向赋值为nil:p = nil;

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

 

 

多对象内存管理:

1:谁创建谁release

如果你通过alloc new 或者[mutable]copy来创建一个对象,那么你必须调用release或者autorelease,换句话说不是你创建的你就不用去[auto]release

2:谁retain谁release

只要你调用了retain,无论这个对象是如何生成的,你都要调用release

 3:总结。

 

1:有始有终,有加有减

2:曾经让对象的计数器+1,最后就必须让对象的计数器-1

 

内存管理规范:

1:只要调用了alloc就必须要有release或者autorelease

2:set方法代码规范:

         1:基本数据类型直接复制

         2:oc对象

-      (void)setCar:(Car*)car

{//首先判断是不是新传进来的对象

           if(car !=_car)

{

           [_car  release];  // 旧对象做一次release

           [car  retain];  // 对新对象进行一次retain

}

dealloc方法代码规范:

1:一定要[super dealloc],而且放到最后面

2:对self(当前对象)所拥有的其他对象进行一次release

-      (void)dealloc

         [_car release];

[super  dealloc];

如果对象不是通过alloc创建的就不需要release

 

@property的内存管理:

@property(retain)Book*book;

         缺点:dealloc方法还是要自己写

property的参数:

1:内存管理相关的参数

retain:release旧值,retain新值

assign:直接赋值,适用于oc非对象类型

copy:release旧值,copy新值

 

2:是否要生成set方法

readonly:只会生成getter的声明和实现

readwrite:同时声明setter和getter方法声明和实现

3:多线程管理

nonatomic:性能高(一般就用这个)

atomic:性能低(默认)

4:setter和getter方法的名称

@property(getter =方法名称)int weight

@property(setter =方法名称:)int weight

一般用在BOOL类型的get方法

返回BOOL类型的方法名一般以is开头,所以可以利用这个来修改get方法的方法名

 

@class仅仅是告诉编译器后面的只是一个类

@class Person  仅仅告诉编译器Person仅仅是一个类

循环调用的时候在声明中用class声明是一个类

在实现中真正用到这个类的时候再导入需要用到的该类

开发中的规范:

1:在.h文件中用@class来声明一个类

2:在.m文件中再用@import导入该类的.h文件

 

循环引用不能释放的问题怎么解决?

1:一端用retain

2:一端用assign(assign是直接赋值,没有retain和release所以在创建和释放计数器是1变成0,这样另一个oc对象就可以释放了。)

例子:比如身份证和人的关系。

 

autorelease:

autorelease方法会返回对象本身。

Autorelease会将对象放到一个自动释放池中

当自动释放池销毁时会对池子里面的所有对象进行一次release操作

Person *p = [[[Person alloc]  init] autorelease]

autorelease对象的计数器不变

@autoreleasepool

         // { 开始代表创建了释放池

         //    }结束代表销毁释放池

将对象放在{}中间

释放池的释放顺序是栈的结构释放,先进后出

我们在程序运行的时候可以创建无数了释放池,释放顺序是先进后出的顺序。

autorelease只是延迟了对象释放的时间。

autorelease不能精确控制对象释放的时间,所以只适合占用内存比较小的时候。

Autorelease好处:

不用在关心对象释放的时间

不用关心什么时候调用release

autorelease注意点:

占用内存比较打的对象不要随便用autorelease

占用内存较小的对象使用autorelease,没有太大影响

 

 

autorelease常见错误:

alloc之后调用了autorelease之后又调用了release是错误的

连续调用多次autorelease也是错误写法。

 

开发中经常会提供一些类方法,快速创建一个已经autorelease过的对象

创建对象时不要直接使用类名,一般用self

+(id)person

{

return[[[self  alloc]  init] autorelease];

}

 

如果创建对象的时候retain一次,那么就必须在delloc方法泗洪release一次

property(retain)只是替代了set方法中的retain和release

释放池autorelease只是代替了对象创建时alloc对应的release

也就是[Person release];

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值