自动释放池和运行/消息循环

  • iOS开发中的内存管理
    • 在iOS开发中,并没有JAVA或C#中的垃圾回收机制
    • 在MRC中对象谁申请,谁释放
    • 使用ARC开发,只是在编译时,编译器会根据代码结构自动添加了retain、release和autorelease.
  • 自动释放池
    • 标记为autorelease的对象,会被添加到最近一次创建的自动释放池中,此时自动释放池会对对象做一次强引用
    • 当自动释放池被销毁或耗尽时,会向自动释放池中的所有对象发送release消息
  • 自动释放池的创建与销毁
    • 创建 : 运行循环检测到事件并启动后,就会创建自动释放池.
    • 销毁 : 一次完整的运行循环结束之前,会被销毁.
  • 运行循环 / 消息循环.
  • 作用
    • 消息循环保证应用程序不退出.
    • 消息循环在循环的扑捉消息,然后执行消息对应的操作.

自动释放池与运行循环的关系

 

什么时候需要手动创建自动释放池?

1、如果在循环中创建了大量的临时变量的时候需要在循环一开始就手动创建一个自动释放池

2、如果你生成一个子线程的时候,要在线程开始执行的时候,尽快创建一个自动释放池.否则会内存泄露.因为子线程无法访问主线程的自动释放池.

 

// 解读:这段代码有什么问题?
for (int i = 0; i < 1000000; ++i) {
    NSString *str = @"Hello World";
    str = [str stringByAppendingFormat:@" - %d", i];
    str = [str uppercaseString];
}

/*
问题:for循环里面创建了大量的临时变量存储在堆区,虽然变量每次都出for循环的作用域,但不会被销毁,因此会导致内存暴涨。
*/

// 解决:每一次循环都加个自动释放池,每次循环之后都释放临时变量。
    for (int i = 0; i < 100000000; ++i) {
        @autoreleasepool {
            NSString *str = @"Hello World";
            str = [str stringByAppendingFormat:@" - %d", i];
            str = [str uppercaseString];
        }
    }

// 注意:如果循环里面是基本数据类型,则不需要,它是系统自动管理的,出了作用域就释放,我们只需要考虑“对象”即可

 

posted @ 2017-01-12 14:20  ys123456789  阅读(458)  评论(0编辑  收藏  举报