2010-06-05 89 views
3

我在學習Objective-C。我試圖釋放所有我使用的內存。所以,我寫了一個程序來測試我是否正確:這個程序爲什麼佔用這麼多內存?

#import <Foundation/Foundation.h> 

#define DEFAULT_NAME @"Unknown" 

@interface Person : NSObject 
{ 
    NSString *name; 
} 
@property (copy) NSString * name; 
@end 

@implementation Person 
@synthesize name; 
- (void) dealloc { 
    [name release]; 
    [super dealloc]; 
} 
- (id) init { 
    if (self = [super init]) { 
    name = DEFAULT_NAME; 
    } 
    return self; 
} 
@end 


int main (int argc, const char * argv[]) { 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 
    Person *person = [[Person alloc] init]; 
    NSString *str; 
    int i; 

    for (i = 0; i < 1e9; i++) { 
    str = [NSString stringWithCString: "Name" encoding: NSUTF8StringEncoding]; 
    person.name = str; 
    [str release]; 
    } 

    [person release]; 
    [pool drain]; 
    return 0; 
} 

我正在使用帶有雪豹的mac。爲了測試它使用的內存量,我在運行的同時打開Activity Monitor。幾秒鐘後,它使用千兆字節的內存。我能做些什麼來使它不那麼用?

回答

5

首先,你的循環是不正確的。 +stringWithCString:…不是+alloc/+new…/-copy方法,所以你應該不是-release吧。

無論是哪種一個是正確的:

  • 不要-release

    str = [NSString stringWithCString: "Name" encoding: NSUTF8StringEncoding]; 
    person.name = str; 
    
  • 使用-init

    str = [[NSString alloc] initWithCString: "Name" encoding: NSUTF8StringEncoding]; 
    person.name = str; 
    [str release]; 
    
  • 同樣,在-[Person init]

    - (id) init { 
        if ((self = [super init])) { 
        name = [DEFAULT_NAME copy]; // <---- 
        } 
        return self; 
    } 
    

    現在,如果你使用的變體#1,內存應該上升到千兆字節,你以前見過,而變異體#2應該是相當恆定的,小的值。

    的差異是因爲

    str = [NSString stringWithCString: "Name" encoding: NSUTF8StringEncoding]; 
    

    相當於

    str = [[[NSString alloc] initWithCString:......] autorelease]; 
    

    一種-autorelease d對象的意思是 「轉移所有權到最近NSAutoreleasePool,並讓它後來釋放它」。

    多晚?默認情況下,當前運行循環打勾一次。但是,您在這裏沒有明確的運行循環*,所以運行循環沒有運行。自動釋放池從來沒有機會清除這些分配的臨時字符串。

    但是,對於變種#2,臨時字符串會立即釋放,因此臨時字符不會填滿內存。 (我們並不需要等待池沖洗 - 有沒有參與池。)


    注:

    *:一個run loop是連接到每個正在運行的線程的唯一循環。如果您編寫CLI實用程序,則很少需要運行循環。

    +0

    非常有幫助,謝謝! – Adrian 2010-06-05 18:30:06

    相關問題