管理的是哪部分内存
- 继承NSObject的类 的对象所占用的内存需要进行管理。
- C语言的数据类型不需要进行管理。
- OC对象使用的内存在堆上,需要管理,而C语言的数据存在在栈中,计算机自动管理。
不进行内存管理或进行了错误的内存管理将导致的结果
- 内存泄漏:程序没有释放不再使用的对象,就会出现该问题。若程序一直申请内存,却不进行释放,那么内存资源终将耗尽。
- 悬挂指针:程序释放了任然在使用的内存,会导致该问题。再次访问释放过的内存,将会出现错误。
对象的生命周期
生命周期包括:
- 诞生:通过alloc、new、copy方法实现。
- 生存:接受消息,执行操作。
- 交友:借助方法的组合和参数。
- 销毁:被释放,不在拥有内存空间。
引用计数
引用计数是OC的内存管理模型。为了知道对象什么时候应该被释放,Cocoa采用了引用计数(也叫保留计数)的技术来确定。具体的说,每一个对象都有一个与之关联的整数,称为引用计数器(也称保留计数器)。当一段代码需要访问一个对象时,该代码就需要将对象的引用计数器加1,结束访问时,需要将引用计数器减1.对象的引用计数器值为0时,表示没有代码使用该对象,此时,对象将被销毁,内存被回收。
如何操作引用计数器
- (instancetype)retain OBJC_ARC_UNAVAILABLE; // 使对象的引用计数器 +1
- (oneway void)release OBJC_ARC_UNAVAILABLE; // 使对象的引用计数器 -1
- (instancetype)autorelease OBJC_ARC_UNAVAILABLE; // 使对象的引用计数器 -1,但何时-1由系统决定。
(NSUInteger)retainCount OBJC_ARC_UNAVAILABLE; // 获取对象当前引用计数器的值
注:当计数器值为0时,OC会向对象发送dealloc消息,释放对象占用的相关资源。请不要手动向对象发送该消息。
- OBJC_ARC_UNAVAILABLE说明了该方法在Objective-C语言中ARC机制下不可使用。
- ARC,automatic reference counting自动引用计数。
自动释放池
1.如何生成一个自动释放池
@autoreleasepool{}
2.使用的注意事项
- 代码写在释放池的{}中间。
- 向对象发送autorelease消息后,释放池在结束时才会向该对象发送release消息。
- 释放池在结束时,之后向加入池中对象发送一次release消息。
内存管理规则
- 当你使用new、alloc、copy方法创建一个对象时,该对象的引用计数器值为1.当不再使用该对象时,你要负责向该对象发送release或者autorelease消息。
- 使用其他方法获取对象,则假设该对象的引用计数器为1,切已经设置了自动释放,你不必对其进行管理;当你拥有该对象,则需要保留(retain),在操作完成后还需要释放这个对象。
如果你保留了某个对象,你需要释放或自动释放该对象。必须保持retain方法和release方法的使用次数相同。
注:
拥有:A对象有个指向B对象的指针成员变量,则A对象拥有B对象。
- 访问:简单的想对象发送消息,并没有设置对象的所有权,也就是上面的拥有。
经典示例
@autoreleasepool{
// do ...
for (int i = 0; i < 1000000; ++i)
{
id object = [someArray objectAtIndex: i];
NSString *desc = [object description];
// do other thing...
}
// do ...
}
上面的循环中,每次都会产生一个(或2个、10个,不知为啥??)自动释放的对象,而自动释放池不会再循环的过程中进行释放,这样就会占用大量内存。需要进行如下修改。
// do ...
for (int i = 0; i < 1000000; ++i)
{
@autoreleasepool{
id object = [someArray objectAtIndex: i];
NSString *desc = [object description];
// do other thing...
}
}
// do ...
}
MRR/MRC和ARC
OC提供的2种内存管理机制:MRR、ARC
gc垃圾回收
1、垃圾回收是运行时工作。
2、启用了gc后,通常用的内存管理命令变成了空操作,不执行任何操作了。
3、gc工作机制是:检查对象及指向对象的指针,发现一个对象没有指针指向它了,那么gc就会清理它。
4、在iPhone程序中,不要使用垃圾回收。