OC学习篇之---数组对象的引用计数问题和自动释放池的概念 分类: IOS 2014-12-14 17:04 1415人阅读 评论(0) 收藏

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

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

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


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

//
//  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方法


2、自动释放池的概念code

//
//  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];blog

//write code...ip

//pool1销毁了作用域

[pool1 release];rem

上面的代码就至关于创建了一个自动释放池pool1,可是在这个中间的代码,若是要加入到这个池中,必须调用autorelease方法:

//dog1放到了pool1中
Dog *dog1 = [[Dog alloc] init];
[dog1 autorelease];
并且,这样定义一个池子还能够嵌套使用,直接看上面的例子代码,这样这个自动释放池咱们就能够控制了。比系统提供的自动释放池可操做的地方不少

下面就直接对比一下:

NSAutoreleasePool *pool1 = [[NSAutoreleasePool allocinit];

这行代码就至关于系统自动释放池的 {

[pool1 release];

这行代码就至关于系统自动释放池的 }

这样就好理解了吧


总结

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

相关文章
相关标签/搜索