Adr*_*ian 3 memory objective-c
我正在学习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;
}
Run Code Online (Sandbox Code Playgroud)
我正在使用带雪豹的mac.要测试它使用了多少内存,我会在它运行的同时打开Activity Monitor.几秒钟后,它正在使用千兆字节的内存.我该怎么办才能让它不那么用?
首先,你的循环不正确.+stringWithCString:…不是+alloc/ +new…/ -copy方法,所以你不应该-release这样.
其中任何一个都是正确的:
不要-release:
str = [NSString stringWithCString: "Name" encoding: NSUTF8StringEncoding];
person.name = str;
Run Code Online (Sandbox Code Playgroud)用途-init:
str = [[NSString alloc] initWithCString: "Name" encoding: NSUTF8StringEncoding];
person.name = str;
[str release];
Run Code Online (Sandbox Code Playgroud)同样,在-[Person init]:
- (id) init {
if ((self = [super init])) {
name = [DEFAULT_NAME copy]; // <----
}
return self;
}
Run Code Online (Sandbox Code Playgroud)
现在,如果你使用变量#1,内存应该像你以前看到的那样上升到千兆字节,而变体#2应该是一个相当恒定的小值.
不同之处在于
str = [NSString stringWithCString: "Name" encoding: NSUTF8StringEncoding];
Run Code Online (Sandbox Code Playgroud)
相当于
str = [[[NSString alloc] initWithCString:......] autorelease];
Run Code Online (Sandbox Code Playgroud)
一个-autoreleased对象是指"的所有权转让给最近的NSAutoreleasePool,并让后来释放它".
多迟?默认情况下,当前运行循环勾选一次.但是,这里没有明确的运行循环*,因此运行循环没有运行.自动释放池永远不会有机会清除这10 个分配的临时字符串.
但是,对于变体#2,临时字符串会立即释放,因此临时字符串不会填满内存.(我们不需要等待池刷新 - 没有涉及池.)
注意:
*:运行循环是附加到每个正在运行的线程的唯一循环.如果编写CLI实用程序,则很少需要运行循环.
| 归档时间: |
|
| 查看次数: |
241 次 |
| 最近记录: |