——- 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
@end
int 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.严格遵循内存管理法则