• OC学习篇之---数组对象的引用计数问题和自动释放池的概念


    之前一片文章中我们介绍了OC中的两个关键字@property和@synthesize的使用的使用:

    http://blog.csdn.net/jiangwei0910410003/article/details/41925967

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


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

    //
    //  main.m
    //  26_NSArrayMemeryManager
    //
    //  Created by jiangwei on 14-10-12.
    //  Copyright (c) 2014年 jiangwei. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    #import "Dog.h"
    
    int main(int argc, const char * 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 jiangwei on 14-10-13.
    //  Copyright (c) 2014年 jiangwei. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    #import "Dog.h"
    
    int main(int argc, const char * 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 allocinit];

    这行代码就相当于系统自动释放池的 {

    [pool1 release];

    这行代码就相当于系统自动释放池的 }

    这样就好理解了吧


    总结

    这一篇文章主要介绍了OC中数组对象操作元素对象的时候需要处理的引用问题,以及我们可以自定义一个自动释放池,这种方式比系统提供的自动释放池方便,可操作性强。





  • 相关阅读:
    心得体会,搞清楚你为什么学习C++?
    完整版本的推箱子小游戏,最简单的纯C语言打造
    联合体、枚举体初步了解及运用
    结构体的初步了解
    使用 Appium 测试微信小程序 Webview——打开调试功能
    Jmeter 使用ssh command 链接linux
    jmeter响应内容乱码问题
    Mac 更新 node版本
    解决jenkins + ant + jmeter发送邮件失败的问题:java.lang.ClassNotFoundException: javax.mail.internet.MimeMessage
    bash特殊字符-2
  • 原文地址:https://www.cnblogs.com/roccheung/p/5797289.html
Copyright © 2020-2023  润新知