【问题标题】:Cocoa Memory Management NSArray with Objects带有对象的 Cocoa 内存管理 NSArray
【发布时间】:2010-03-09 18:29:42
【问题描述】:

我在释放对象时遇到了麻烦。为了更好地解释它,我在下面包含了我的代码。

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];

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

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

感谢您的帮助!

【问题讨论】:

  • 好的,您分配string 的代码简直是疯了。将其分解为更小的线条和泄漏等变得更加明显。

标签: cocoa memory-management


【解决方案1】:

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

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

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

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

【讨论】:

  • +1 用于引用文档。没有比内存管理文档更能说明这一点的地方了。
  • 谢谢!我修复了 NSPipe 泄漏。是的,我故意留下了论点等。
【解决方案2】:

substringToIndex: 返回一个自动释放的字符串,所以不需要release 它。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-12
    • 1970-01-01
    相关资源
    最近更新 更多