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中數組對象操做元素對象的時候須要處理的引用問題,以及咱們能夠自定義一個自動釋放池,這種方式比系統提供的自動釋放池方便,可操做性強。

相關文章
相關標籤/搜索