OC视频笔记(内存管理)

来源:互联网 发布:南京风水 知乎 编辑:程序博客网 时间:2024/05/21 03:24

OC内存管理

一、基本原理

(一)为什么要进行内存管理。

由于移动设备的内存极其有限,所以每个APP所占的内存也是有限制的,当app所占用的内存较多时,系统就会发出内存警告,这时需要回收一些不需要再继续使用的内存空间,比如回收一些不再使用的对象和变量等。

管理范围:任何继承NSObject的对象,对其他的基本数据类型无效。

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

 

(二)对象的基本结构

每个OC对象都有自己的引用计数器,是一个整数表示对象被引用的次数,即现在有多少东西在使用这个对象。对象刚被创建时,默认计数器值为1,当计数器的值变为0时,则对象销毁。

在每个OC对象内部,都专门有4个字节的存储空间来存储引用计数器。


(三)引用计数器的作用

       判断对象要不要回收的唯一依据就是计数器是否为0,若不为0则存在。

(四)操作

给对象发送消息,进行相应的计数器操作。

     alloc用来创建对象,创建对象后,引用计数为1,只调用一次。

Retain消息:使计数器+1,该方法返回对象本身,可多次调用。

Release消息:使计数器-1(并不代表释放对象),可调用多次。

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

当引用计数为0的时候,对象会被系统从内存中销毁,销毁之前会自动调用该对象的dealloc方法。


(五) 对象的销毁

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

当对象被销毁时,系统会自动向对象发送一条dealloc消息,一般会重写dealloc方法。dealloc就像是对象的“临终遗言”。一旦重写了dealloc方法就必须调用[super dealloc],并且放在代码块的最后调用(不能直接调用dealloc方法)。

-(void)dealloc{

    NSLog(@“妈的,我被销毁了。”);

    [super dealloc];

}

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


二、对象所有权

      当一个所有者(本身是一个OC对象),当它做了如下的动作,它就拥有了一个对象的所有权:

         alloc              retain                        【mutable】copy

         使用如下方法释放所有权:

                      release                             autorelease

三、相关概念和使用注意

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

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

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

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

四、内存管理原则

(一)原则

只要还有人在使用某个对象,那么这个对象就不会被回收;

只要你想使用这个对象,那么就应该让这个对象的引用计数器+1

当你不想使用这个对象时,应该让对象的引用计数器-1

(二)谁创建,谁release

(1)如果你通过alloc,new,copy来创建了一个对象,那么你就必须调用相应的release或者autorelease方法将其释放

(2)不是你创建的就不用你去负责

(三)谁retain,谁release

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

(四)总结

有始有终,有加就应该有减。曾经让某个对象计数器加1,就应该让其在最后-1.

五、内存管理代码规范

(一)只要调用了alloc,就必须有release(autorelease)

(二)Set方法的代码规范

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

-voidsetAge:(int)age

{

_age=age;

}

(2)OC对象类型

-voidsetCar:(Car *)car

{

//1.先判断是不是新传进来的对象

If(car!=_car)

{

//2 对旧对象做一次release

[_car release];//若没有旧对象,则没有影响。不要纠结这句话,没有旧对象就是没有影响,想明白怎么回事就去看API啊。

//3.对新对象做一次retain

_car=[car retain];

}

}

(三)dealloc方法的代码规范

(1)一定要[super dealloc],而且要放到最后//[super dealloc]是调用父类的dealloc方法,让父类释放父类所持有的对象

(2)对self(当前)所拥有的的其他对象做一次release操作(解释一下,当一个对象用到dealloc方法的时候,就是说明该对象的引用计数为0了,要释放这个对象所占用的空间了,如果释放了这个对象,那么这个对象本身要是还有别的对象存在的话,就没有任何意义了,所以要对self所拥有的其他对象进行relase)

-voiddealloc

{

[_car release];

[super dealloc];

}

六、@property的参数

    举一个例子:在类的声明文件(.h文件)写类方法的地方(大括号外面)有:

      @property(Nonatomic,copy,ReadWrite) NSString *strName;

      那么@property会自动生成一个_strName(带下划线的属性)属性,并且为该属性生成set和get方法。但是是默认的不会显示出来。如果想让@property生成的名字有所改动的话,可以在.m文件里面使用@synthesize后面加新的属性名的形式更改生成的属性名字。(@synthesize strName = ¥¥¥¥;)那么@property NSString *strName;生成的属性名字就是¥¥¥¥了。

                   1  多线程管理(苹果在一定程度上屏蔽了多线程操作)

      Nonatomic:高性能,一般使用这个

       Atomic:低性能(默认的)


      2.@property创建属性一共有三种形式(想要哪种形式就在@property(1,2,3)这里设置):

       (1).普通的赋值形式:Assign:直接赋值(默认,适用于非oc对象类型)

         -(void)setStrName{

          -strName = strName;

          }

       (2).第二种形式是retain,Retain:对对象release旧值,retain新值(适用于OC对象类型)

          -(void)setStrName

         {

          if(_strName!=strName)

          【_strName release】;

          _strName = [strName retain];

          }

       (3).第三种形式是copy:Copy:release旧值,copy新值(OC中NSString对象的引用计数持有,用copy)

          -(void)setStrName

         {

          if(_strName!=strName)

          【_strName release】;

          _strName = [strName copy];

          }


3.是否要生成set方法(若为只读属性,则不生成)

Readonly:只读,只会生成getter的声明和实现

Readwrite:默认的,同时生成settergetter的声明和实现

 


 

(4)Setget方法的名称

修改setget方法的名称,主要用于布尔类型。因为返回布尔类型的方法名一般以is开头,修改名称一般用在布尔类型中的getter

@propery(setter=setAbc,getter=isRich) BOOL rich;

BOOL b=p.isRich;// 调用

 

 




0 0
原创粉丝点击