iOS内存管理相关知识点

iOS 开发:彻底理解 iOS 内存管理(MRC、ARC)
内存分为5个区域:栈区、堆区、bss段、数据区、代码段;
栈:存放的是局部变量,当局部变量的作用域结束的时候就会由系统进行释放局部变量所占用的内存空间;
堆:存放的是程序员手动申请的变量,手动申请的变量可以由程序员手动编写代码进行释放;
bss段:存放的是为初始化的全局变量和静态变量,当全局变量和静态变量进行初始化的时候系统就会回收他们所占用的空间,然后把他们存放到数据段;
数据段:存放的是已经初始化了的全局变量和静态变量和常量,当程序结束的时候由系统进行回收释放;
代码段:存放的是我们编写的代码,当程序结束的时候由系统进行回收释放;

所以需要我们自己进行内存管理的其实只有堆区。

1.MRC和ARC

MRC:也叫手动引用计数,在MRC机制下,每一个对象都有一个四个字节的存储空间(一个整数),记录对象被引用的数量,一个对象被创建出来以后,默认的引用计数为1,谁引用当前对象,就把引用计数+1,当一个对象引用计数为零的时候,对象会被立即回收,所以我们可以通过对引用计数的操作来进行对象的回收,并完成内存空间的操作;
手动计数器使用规则:谁用谁retain,谁不用谁release。

Person* p = [Person new];//默认retainCount就是1 ,所以这里的p不需要手动操作。

Person* p2 = p;
[p2 retain];//将retainCount的值+1;

当p2指针不使用此堆空间了。要手动把 retainCount 值 - 1
[p2 release];

p不用了,也需要release
[p release];

ARC:自动引用计数

系统会在合适的地方插入retain, release和autorelease,自动生成正确的代码去自动释放或者保持对象。不用我们手动管理

2.关于自动释放池
MRC下

NSAutoreleasePool *pool = [[ NSAutoreleasePool alloc]init ];//创建一个自动释放池
Person *person = [[Person alloc]init];
//调autorelease方法将对象加入到自动释放池
[person autorelease];
//手动释放自动释放池执行完这行代码是,自动释放池会对加入他中的对象做一次release操作
[pool release];
···
自动释放池销毁时机:[pool release]代码执行完后.

ARC下

@autoreleasepool {
    //在这个{}之内的变量默认被添加到自动释放池
    Person *p = [[Person alloc] init];
}//出了这个括号,p被释放

3.循环引用
ARC和MRC一样,如果A拥有B,B也拥有A,那么必须一方使用弱指针

@interface Person : NSObject
@property (nonatomic, strong) Dog *dog;
@end

@interface Dog : NSObject
// 错误写法, 循环引用会导致内存泄露
//@property (nonatomic, strong) Person *owner;

// 正确写法, 当如果保存对象建议使用weak
@property (nonatomic, weak) Person *owner;
@end

4.野指针、空指针和僵尸对象

僵尸对象:一个被释放了的不能再用的对象,我们称之为僵尸对象
野指针:当一个指针指向一个僵尸对象(不可用内存),我们就称这个指针为野指针
空指针:一个指向nil的指针,给空指针发消息是没有任何反应的。

你可能感兴趣的:(iOS内存管理相关知识点)