• Objective


    前面我们学了OC内存管理的手动引用计数, 一个alloc, 一个release, 对象的释放由我们自己所决定, 在这里应该会有人问, 这样子运用手动引用计数好累, 有没有简单一点的方法, 答案肯定是有的, 现在我们就来看看第一个简单一点的方法, autorelease方法.


    首先我们来看看以前所写的例子:

    #import <Foundation/Foundation.h>
    
    @interface Person : NSObject
    
    @property (nonatomic, assign)int age;
    
    @end
    
    #import "Person.h"
    
    @implementation Person
    
    - (void)dealloc
    {
        NSLog(@"Person对象被释放了.");
        
        [super dealloc];
    }
    
    @end
    

    #import <Foundation/Foundation.h>
    #import "Person.h"
    
    int main(int argc, const char * argv[])
    {
        Person *p = [[Person alloc] init];
        
        p.age = 10;
        
        [p release];
        return 0;
    }
    

    打印出来的结果:

    2015-01-27 16:39:19.419 08.autorelease基本认识[6599:712028] Person对象被释放了.
    





    这个就是我们之前所写的例子, 在main()函数中, 我们必须得把release写在各种操作之后, 否则就会出现野指针错误, 这个我们在前面就已经知道了, 虽然这样子做可以非常的精准, 但很累人, 所以autorelease出现了, 我们看看修改后的例子:

    #import <Foundation/Foundation.h>
    #import "Person.h"
    
    int main(int argc, const char * argv[])
    {
        
        @autoreleasepool
        {
            Person *p = [[Person alloc] autorelease];
            
            p.age = 10;
        }
        
        return 0;
    }

    打印出来的结果:

    2015-01-27 16:43:29.602 08.autorelease基本认识[6619:713881] Person对象被释放了.
    


    使用了autorelease一样可以让对象被释放~~这样子我们在main()函数里写对象的时候就再去担心对象没有被release.




    但注意一下, autorelease的作用并不是释放对象, 只是建造一个自动内存池, 把对象放进去, 只要内存池被销毁, 对象才会被release, 并不是直接释放对象.



    还有, autorelease是可以多重嵌套使用的, 比如:

    #import <Foundation/Foundation.h>
    #import "Person.h"
    
    int main(int argc, const char * argv[])
    {
        
        @autoreleasepool
        {
            Person *p = [[Person alloc] autorelease];
            
            p.age = 10;
            
            @autoreleasepool {
                Person *p1 = [[Person alloc] autorelease];
                
                p1.age = 20;
            }
        }
        
        return 0;
    }
    

    打印出来的结果:

    2015-01-27 17:19:34.054 08.autorelease基本认识[6672:721475] Person对象被释放了.
    2015-01-27 17:19:34.055 08.autorelease基本认识[6672:721475] Person对象被释放了.
    



    注意一点, autorelease使用的场景一般是在占用内存比较小的对象下使用, 比如一个对象里面几乎都是基本数据类型的, 如果是占用内存比较大的对象, 最好还是使用手动引用计数, 否则会引起内存泄漏.



    autorelease的错误写法:

    1> alloc之后调用了autorelease,又调用release

     @autoreleasepool
     {
        // 1
        Person *p = [[[Person alloc] init] autorelease];
     
        // 0
        [p release];
     }
    


    2> 连续调用多次autorelease

     @autoreleasepool
     {
        Person *p = [[[[Person alloc] init] autorelease] autorelease];
     }
    





    下面我们来总结一下:

    1.autorelease的基本用法

    1> 会将对象放到一个自动释放池中

    2> 当自动释放池被销毁时,会对池子里面的所有对象做一次release操作

    3> 会返回对象本身

    4> 调用完autorelease方法后,对象的计数器不变

     

    2.autorelease的好处

    1> 不用再关心对象释放的时间

    2> 不用再关心什么时候调用release

     

    3.autorelease的使用注意

    1> 占用内存较大的对象不要随便使用autorelease

    2> 占用内存较小的对象使用autorelease,没有太大影响


    4.自动释放池

    1> iOS程序运行过程中,会创建无数个池子。这些池子都是以栈结构存在(先进后出)

    2> 当一个对象调用autorelease方法时,会将这个对象放到栈顶的释放池




    好了, 这次我们就讲到这里, 下次我们继续~~

  • 相关阅读:
    php xml解析方法
    phpmail 发送邮件失败
    善用Eclipse的代码模板功能
    php5.3 namespace
    MyEclipse6.5配置反编译插件
    程序bug致损失400亿,判程序员坐牢? 搞笑我们是认真的
    ios学习笔记(二)第一个应用程序--Hello World
    ios学习笔记(一)Windows7上使用VMWare搭建iPhone开发环境
    GJB150-2009军用装备实验室环境试验方法新版标准
    AXI总线简介
  • 原文地址:https://www.cnblogs.com/iOSCain/p/4282822.html
Copyright © 2020-2023  润新知