黑马程序员 内存管理1

来源:互联网 发布:阿里云员工救人 编辑:程序博客网 时间:2024/05/04 13:35

——- android培训、java培训、ios培训期待与您交流!

一、堆、栈

堆栈空间分配
定义:
栈(操作系统):由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
堆(操作系统): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收。

二、内存管理

任何继承与NSObject类的对象都属于OC类型。所有OC对象都有一个计数器,保留着当前被引用的数量。基本数据类型不需要管理内存。

2.1 alloc、retain、release方法

1)alloc 函数是创建对象使用,创建完成后计数器为1;只用1次。2)retain是对一个对象的计数器+1;可以调用多次。    -(id)retain;返回的是对象本身3)release是对一个对象计数器-1;减到0对象就会从内存中释放。

2.2 僵尸对象

一个对象被释放后,内存不可用,此时的对象被称之为僵尸对象。

2.3 野指针、空指针

野指针:指向僵尸对象的指针(或者指向不可用内存的指针)被称之为野指针。
空指针:没有指向任何东西的指针(存储的东西是nil、null或者0)

2.4 retainCount方法

retainCount方法,返回对象被引用的次数

-(unsigned)retainCount;

使用方式:
int count=[对象名 retainCount];

2.5内存管理法则

有始有终,有加就有减

1.谁创建,谁release
谁通过alloc,new或者copy创建对象,谁就必须调用release释放对象
2.谁retain,谁release
谁调用了retain,无论这个对象是如何生成的,谁就必须调用release

三、set方法内存管理

如果一个对象具有指向其他对象的变量,那么该对象就拥有了那个对象。

3.1

假如在main中实例化了两个对象A和B,此时A和B 的计数器值均为1,如果A拥有B,需要将B传递给A,也就是说B被两处使用,此时B的计数器值为2,根据内存管理法则,有加就得有减,在哪里减呢?谁加,谁负责。赋值工作是在set方法中完成的,因此,减去的责任也是在set方法。
例如:

//Person类@interface Person :NSObject{    // 具有一个Car类型的属性,Car 是一个类    Car *_car;}- (Car *)car;- (void)setCar:(Car *)car;@end@implementation Person- (Car *)car{    return _car;}- (void)setCar:(Car *)car{    _car=car;}@end//Car类@interface Car:NSObject@end@implementation@endint main(){    //p计数器值1    Person *p=[[Person alloc] init];    //c计数器值1    Car *c=[[Car alloc] init];    //c计数器值2    p.setCar=c;    //c计数器值1    [c release];    //p计数器值0,被释放    [p release];}

上述例子中c的计数器并不为0,p对象已经被释放了,那么它所包含的变量也就不应该存在了,因此必须修改代码,释放c
修改如下,在Person类中的set方法进行修改:

- (void)setCar:(Car *)car{    if(car!=_car)    {        [_car release];        _car=[car retain];    }}

3.2 重写dealloc方法

dealloc方法在对象被销毁时调用的方法,就像是对象最后的遗言。
重写dealloc方法必须调用[super dealloc],且这句调用要放到最后。
代码如下:

- (void)dealloc{    //代码    //比如这个类包含另一个类,将那个类的计数器减1    [对象名 release];    [super dealloc];}

每个对象都会调用一次

四、总结

4.1 为什么进行内存管理

对象存储在堆中,堆中的数据程序结束前不会 自动释放,无用的对象会继续占用系统的内存空间,而手机的内存空间是有限的,超过一定的限度就会造成内存不足,卡机,闪退等现象。进行内存管理,及时的释放内存空间,大大优化了app的工作效率,提高了用户体验。

4.2 内存管理的本质

每一个对象都会被分配四个字节的内存空间,用于存储对象的引用计数器,通过对对象的引用计数器的管理,来管理内存。当对象的引用计数器为1时,释放对象的内存空间。

4.3 内存管理的注意

1.避免野指针错误:指针指向僵尸对象(不可用的内存空间)2.避免内存释放不彻底:set方法中应先对对象进行释放,然后再赋值3.重写dealloc方法:方法的最后必须调用[super dealloc]4.严格遵循内存管理法则
0 0
原创粉丝点击