zoukankan      html  css  js  c++  java
  • 黑马程序员--Objective-C之--自动释放池的概念以及使用

     

    ------IOS培训期待与您交流! -------

     

    今天我们来看一下OC中数组对象在是如何处理对象元素的引用计数问题的,同时介绍一下自动释放池的相关概念

     一、数组对象是如何处理对象元素的引用计数问题

     

        //  
        //  main.m  
        //  26_NSArrayMemeryManager  
        //  
        //  Created by waterfoxjie on 15-03-29.  
        //  Copyright (c) 2015年 waterfoxjie. All rights reserved.  
        //  
          
        #import <Foundation/Foundation.h>  
          
        #import "Dog.h"  
          
        int main(int argc, const charchar * argv[]) {  
              
            Dog *dog1 = [[Dog alloc] init];  
            Dog *dog2 = [[Dog alloc] init];  
              
            NSMutableArray *array = [[NSMutableArray alloc] init];  
              
            //数组会对每一个元素retain  
            [array addObject:dog1]; //dog1计数=2  
            [array addObject:dog2]; //dog2计数=2  
              
            [dog1 release];  
            [dog2 release];  
              
            //当数组销毁的时候,会将所有的元素release  
            [array release];//数组销毁  
              
            //当数组移除所有的元素的时候,会讲所有的元素release  
            [array removeAllObjects];  
              
            return 0;  
        }  

    我们定义了Dog类,然后定义了NSMutableArray数组存放两个Dog对象,OC中在将对象放到数组中的时候,会自动调用retain方法,当数组对象本身被销毁的时候,会调用

    所有元素的release方法,当移除数组中所有的元素的时候,会调用元素的release方法

     

    二、自动释放池的概念

        //  
        //  main.m  
        //  27_AutoReleasePool  
        //  
        //  Created by waterfoxjie on 15-03-29.  
        //  Copyright (c) 2015年 waterfoxjie. All rights reserved.  
        //  
          
        #import <Foundation/Foundation.h>  
          
        #import "Dog.h"  
          
        int main(int argc, const charchar * argv[]) {  
              
            /* 
            //创建一个自动释放池 
            //有作用域的问题,在{}中定义的东西外部是不能访问的,这点和NSAutoreleasePool有区别的
    @autoreleasepool {//等价于[[NSAutoreleasePool alloc] init] Dog *dog2 = [[Dog alloc] init]; [dog2 retain]; }//等价于[pool release] //创建一个自动释放池 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; Dog *dog1 = [[Dog alloc] init];//计数:1 //将dog1对象加入到自动释放池中,却别于之前的release方法 //加入到自动释放池中之后,不是代表我们不需要管理引用了,只是自动释放池自动会调用一次release //当自动释放池销毁的时候,释放池会对池中每一个对象调用一次release
    [dog1 autorelease];
    NSLog(@"dog1计数:%ld",dog1.retainCount); //销毁自动释放池 //这时候会调用dog1的release方法,dog1对象就被销毁了 [pool release];
    */ //自动释放池的嵌套 NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init]; //添加我们的代码 //dog1放到了pool1中 Dog *dog1 = [[Dog alloc] init]; [dog1 autorelease]; //自动释放池的嵌套 NSAutoreleasePool *pool2 = [[NSAutoreleasePool alloc] init]; //dog2放到了pool2中 Dog *dog2 = [[Dog alloc] init]; [dog2 autorelease]; //pool2销毁了 [pool2 autorelease]; //pool1销毁了 [pool1 release]; //下面的代码就是有问题的 //[person setDog:[[Dog alloc] init]; //正确的写法 //Dog *dogs = [[[Dog alloc] init] autorelease]; return 0; }

    我们在之前的文章中,定义一个对象的时候都会产生一个自动释放池,然后在释放池中编写我们的代码,自动释放池是系统提供的一种帮助我们去管理对象的引用计数问题。

    但是有时候代码必须在{...}中编写,这样的话就会产生作用域的问题,就是在{...}中定义的变量,在{...}外面不能使用。

    所以OC中就有 了另外的一种方式:NSAutoreleasePool这个类

    这种自动释放池可以实现嵌套

     

    NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init];
    
    //write code...
    //pool1销毁了 [pool1 release];

    上面的代码就相当于建立了一个自动释放池pool1,但是在这个中间的代码,如果要加入到这个池中,必须调用autorelease方法:

     

    //dog1放到了pool1中  
    Dog *dog1 = [[Dog alloc] init];
    [dog1 autorelease];

    而且,这样定义一个池子还可以嵌套使用,直接看上面的例子代码,这样这个自动释放池我们就可以控制了。比系统提供的自动释放池可操作的地方很多

    下面就直接对比一下:

     

    NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init];
    
    //这行代码就相当于系统自动释放池的
    {
    
    [pool1 release];
    
    //这行代码就相当于系统自动释放池的 
    }

     

    这样就好理解了吧

     

  • 相关阅读:
    django-高级
    django-模板
    django-视图
    django笔记一
    redis、mysql、mongodb数据库
    Scrapy-redis分布式+Scrapy-redis实战
    python2 'ascii'编码问题
    【java8新特性】方法引用
    java浮点数运算无法精确的问题
    java中Array和ArrayList区别
  • 原文地址:https://www.cnblogs.com/waterfox/p/4376921.html
Copyright © 2011-2022 走看看