可可内存管理NSArray与对象

时间:2010-03-09 18:29:42

标签: cocoa memory-management

我遇到了释放物品的麻烦..为了更好地解释它,我在下面加入了我的代码。

NSTask *task = [NSTask new];
NSTask *grep = [NSTask new]; 
NSPipe *pipe = [NSPipe new];

[task setStandardError: pipe];
[grep setStandardInput: pipe];
[pipe release];
pipe = [NSPipe new];
[grep setStandardOutput: pipe];

[task launch];
[grep launch];

NSString *string = [[[[[[NSString alloc] initWithData: [[[grep standardOutput] fileHandleForReading] readDataToEndOfFile] encoding: NSASCIIStringEncoding] autorelease] componentsSeparatedByString: @" "] objectAtIndex: 3] substringToIndex: 8];

NSMutableDictionary *dict = [NSMutableDictionary new];
[dict setObject: string forKey: @"myKey"];
[records addObject: dict];
[dict release];

[task release];
[grep release];
[pipe release];

我如何释放字符串,是否还有其他泄漏?另外,如果我使用records删除数组removeAllObjects中的所有内容,那么一切都会好吗?数组永远不应该被释放并且始终可用,我只是担心它的对象。

编辑:指出的唯一泄漏与NSPipe有关,应该在代码中修复。

感谢您的帮助!

2 个答案:

答案 0 :(得分:4)

Objective-C中的内存管理有一个fundamental rule

  

如果使用名称以“alloc”或“new”开头或包含“copy”(例如,alloc,newObject或mutableCopy)的方法创建对象,或者如果发送它,则获取对象的所有权保留信息。您有责任使用release或autorelease放弃您拥有的对象的所有权。在收到对象的任何其他时间,您都不能释放它。

因此,代码示例中对new的每次调用都应与对releaseautorelease的调用保持平衡。 NSArray以及代码中的大多数其他对象都不是使用它们创建的,因此不需要释放它。 [NSString alloc]是自动释放的,因此需要处理。集合管理自己的项目,根据需要保留和释放它们:当插入项目时,它会被保留;当它被删除时,它被释放了。字典键被复制而不是保留。

你有一个不平衡的new(因此泄漏)是你创建的第一个NSPipe。在为grep的标准输出创建管道之前释放它。也许您只是将其从样本中删除,但您也没有为grep任务设置任何参数。

答案 1 :(得分:1)

substringToIndex:会返回一个自动释放的字符串,因此无需release

我看到的唯一内存泄漏是您第二次设置'pipe'var(对于任务的标准输出)而没有先释放其当前值(用于标准错误和输入的NSPipe实例)。

像NSMutableArray这样的可变集合将保留它们包含的对象(与所有可变/不可变集合一样),然后在它们被删除时释放它们(或者当集合本身被释放时)。