黑马程序员——OC内存管理

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 
一. 原理
1.对于任何继承了NSObject的对象,都有一个与之关联的整形变量,称为引用计数器;只有计数器的值为0的时候,OC就回收该对象,否则永不回收。
2.当使用release方法释放时,计数器的值减1
3. 当使用retain方法时,计数器的值加1
4. 当对象被回收时候,自动调用对象的dealloc方法
5. 使用retainCount方法来获取引用计数器的值
6. autorelease pool
6.1 autorelease pool ,需要手动创立。autorelease pool 的真名是 NSAutoreleasePool。NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
6.2 NSAutoreleasePool 内部包含一个数组(NSMutableArray),用来保存声 明为 autorelease 的所有对象。如果一个对象声明为 autorelease,系统所做的 工作就是把这个对象加入到这个数组中去。

ClassA *obj1 = [[[ClassA alloc] init] autorelease]; //retain coun t = 1,把此对象加入 autorelease pool 中

ClassA *obj1 = [[[ClassA alloc] init] autorelease]; //retain coun t = 1,把此对象加入 autorelease pool 中
6.3 NSAutoreleasePool 自身在销毁的时候,会遍历一遍这个数组,release 数组中的每个成员。如果此时数组中成员的 retain count 为 1,那么 release 之后,retain count 为 0,对象正式被销毁。如果此时数组中成员的 retain count 大于 1,那么 release 之后,retain count 大于 0,此对象依然没有被销毁, 内存泄露。
6.4 默认只有一个 autorelease pool,通常类似于下面这个例子。
{
    NSAutoreleasePool *pool;
    pool = [[NSAutoreleasePool alloc] init];
    // do something
    [pool release];
    return 0;
}

{
    @autoreleasePool{
//do something
    }
    return 0;
}

 


所有标记为 autorelease 的对象都只有在这个 pool 销毁时才被销毁。如果 你有大量的对象标记为 autorelease,这显然不能很好的利用内存.(自己网上查资料看到的一道面试题)
  
 int main (int argc, const char *argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int i, j;
    for (i = 0; i < 100; i  )
{
    for (j = 0; j < 100000; j  )
[NSString stringWithFormat:@"1234567890"];//产生的对象是 autorelease 的。
    }
    [pool release];
    return (0);
    } 



7. Objective-C 程序中可以嵌套创建多个 autorelease pool。在需要大量创 建局部变量的时候,可以创建内嵌的 autorelease pool 来及时释放内存
int main (int argc, const char *argv[])
    {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    int i, j;
    for (i = 0; i < 100; i  )
    {
    NSAutoreleasePool *loopPool = [[NSAutoreleasePool alloc] init];
    for (j = 0; j < 100000; j  )
[NSString stringWithFormat:@"1234567890"];//产生的对象是 autorele ase 的。
    [loopPool release];
    }
    [pool release];
    return (0);
} 





二. 口诀

1 谁创建,谁释放(类似于“谁污染,谁治理”)。如果通过 alloc、new 或 copy 来创建一个对象,那么必须调用 release 或 autorelease。换句话说, 不是你创建的,就不用你去释放。
例如,你在一个函数中 alloc 生成了一个对象,且这个对象只在这个函数中 被使用,那么你必须在这个函数中调用 release 或 autorelease。如果在一个 class 的某个方法中 alloc 一个成员对象,且没有调用 autorelease,那么需要在这个类的 dealloc 方法中调用 release;如果调用了 autorelease,那么在 dealloc 方法中什么都不需要做。
2 除了 alloc、new 或 copy 之外的方法创建的对象都被声明了 autorelease。
3 谁 retain,谁 release。只要你调用了 retain,无论这个对象是如何生成的,你都要调用 release。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值