带有对象的 Cocoa 内存管理 NSArray

Jef*_*Jef 0 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];
Run Code Online (Sandbox Code Playgroud)

我将如何释放字符串,是否还有其他泄漏?另外,如果我从数组中删除所有recordsremoveAllObjects被释放的一切好,然后呢?数组永远不应该被释放并且一直可用,我只是担心它的对象。

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

谢谢你的帮助!

out*_*tis 5

Objective-C 中的内存管理有一个基本规则

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

因此new,您的代码示例中的每次调用都应该与对releaseor的调用相平衡autorelease。的NSArray,与代码中大多数其他的目的,不与任何创建的,所以它并不需要被释放。该[NSString alloc]会被自动释放,因此它的照顾。集合管理它们自己的项目,根据需要保留和释放它们:当一个项目被插入时,它被保留;当它被移除时,它被释放。字典键被复制而不是保留。

不平衡new(因此泄漏)的地方是NSPipe您创建的第一个地方。在为 grep 的标准输出创建管道之前释放它。也许您只是将它排除在示例之外,但您也没有为 grep 任务设置任何参数。