内存大总结

内存管理大总结

1.自动引用计数的概念

  • 在OC中采用引用计数机制来管理对象的生命周期.

  • 在实际的项目中,我们在函数内使用一个临时的对象,通常是不需要修改它的引用计数的,只需要在函数返回前将该对象销毁即可.

  • 引用计数真正排上用场是,对象之间传递和共享数据.遵从引用计数这个规则的话,对象的生命周期的管理就完全可以交给引用计数了.

2.内存管理/引用计数

2.1.1 内存管理的思考方式

举例 对办公室照明设备所做的动作和对OC对象所做的动作

对照明设备所做的动作 对OC对象所做的动作 OC方法
开灯 生成并持有对象 alloc/copy/new/mutableCopy等方法
需要照明 持有对象 retain方法
不需要照明 释放对象 release方法
关灯 废弃对象 dealloc方法

小结:

  • 自己生成的对象,自己持有
  • 非自己生成的对象.自己也可以持有
  • 不再需要自己持有的对象时释放
  • 非自己持有的对象无法释放

这些有关的OC内存管理的方法,实际上不包括在该语言中,而是包含在Cocoa框架中用于OSX iOS应用开发.Cocoa框架中的Foundation框架类库中的NSObject类担负内存管理的职责.OC内存管理中的alloc/retain/release/dealloc方法分别指代NSObject类的alloc类方法,retain实例方法,release实例方法和dealloc实例方法.

  • 自己生成对象并持有.举例:
    NSArray *arr1 = [[NSArray alloc]init]; //取得对象,并持有;
  • 非自己生成的对象,即使用alloc/copy/new/mutableCopy以外的方法取得的对象,也可以持有.举例:
    NSArray *arr2 = [NSArray array];//取得对象,但并不持有;
    [arr2 retain];//自己持有对象
  • 不再需要自己持有的对象时释放.举例[arr1/arr2 release];特殊的是 针对arr1,自己生成并持有的对象,可以采用 [arr1 autorelease];,因为autorelease提供这样的功能,使对象在超出指定的生存范围时能够自动并正确的释放(调用release方法).
  • 无法释放非自己持有的对象:如果对象的引用计数已经为0,则不能再次释放,非自己持有的对象更不能释放.

release和autorelease的区别

release autorelease
对象立即释放 对象不立即释放,注册到autoreleasepool中,pool结束时自动调用release

2.1.2 alloc/retain/release/dealloc实现

  • 在OC的对象中存有引用计数这一整数值(retainCount)
  • 调用alloc/new/copy/mutableCopy/retain方法后,引用计数值+1.
  • 调用release后,引用计数-1.
  • 引用计数为0时,调用dealloc方法废弃对象

2.1.5 autorelease

autorelease的具体使用方法如下:

  • 生成并持有NSAutoreleasePool对象;
  • 调用已分配对象的autorelease实例方法;
  • 废弃NSAutoreleasePool对象.
NSAutoreleasePool *pool = [][NSAutoreleasePool alloc]init];
id obj = [[NSObect alloc]init];
[obj autorelease];
[pool drain];

尽管如此,当在大量产生autorelease对象时,只要不废弃NSAutoreleasePool对象,那么生成的对象就不能被释放,因此有时候会产生内存不足的现象.正确的做法是 把自动释放池的创建放在for循环内.代码如下:

for(int i = 0; i< 100000;i++)
{
NSAutoreleasePool *pool = [][NSAutoreleasePool alloc]init];
//读入图像,产生大量`autorelease`的对象.

[pool drain];

}

在OC中,也就是Foundation框架时,无论调用哪一个对象的autorelease实例方法,实际上调用的都是NSObject类的autorelease实例方法.但是对于NSAutoreleasePool类,autorelease实例方法已被该类重载,因此运行就会报错.

//这样写是错误滴
NSAutoreleasePool *pool = [][NSAutoreleasePool alloc]init];
[pool autorelease];

原文地址:https://www.cnblogs.com/xlp724619666/p/5689023.html