2010-06-05 56 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

    相关问题