两个Objective-C内存管理问题:泄漏检测是否始终正确?为什么autorelease工作但不释放?

Xan*_*unn 3 iphone memory-leaks memory-management objective-c

我刚刚发现了以下内容:正如我所料,在我返回它之前释放我的对象会导致应用程序崩溃:

   + (NSString *)descriptionOfExpression:(NSArray *)anExpression {
    NSMutableString *expressionDescription;
    expressionDescription = [[NSMutableString alloc] init];  
    for (id object in anExpression) {
    //Do stuff to expressionDescription
    }

    [expressionDescription release];
    return expressionDescription;
}
Run Code Online (Sandbox Code Playgroud)

但是,我没想到以下会导致内存泄漏:

    + (NSString *)descriptionOfExpression:(NSArray *)anExpression {
    NSMutableString *expressionDescription;
    expressionDescription = [[NSMutableString alloc] init];  
    for (id object in anExpression) {
    //Do stuff to expressionDescription
    }

    return expressionDescription;
    [expressionDescription release];
}
Run Code Online (Sandbox Code Playgroud)

最终,我的解决方案是这样做,而是:

    + (NSString *)descriptionOfExpression:(NSArray *)anExpression {
    NSMutableString *expressionDescription;
    expressionDescription = [[NSMutableString alloc] init];  
    for (id object in anExpression) {
    //Do stuff to expressionDescription
    }

    [expressionDescription autorelease];
    return expressionDescription;
}
Run Code Online (Sandbox Code Playgroud)

我理解为什么自动释放它有效,但是如何在返回值后释放导致泄漏?

我的第二个问题非常相关:内存泄漏检测系统是否总是正确的?

我意识到开发了仪器和XCode的构建和分析功能的程序员在这方面比我更有经验,所以现在我将假设他们总是正确的.但是,我很难理解像Instruments这样的程序如何"知道"内存被泄露.我认为它应该完全取决于我,程序员,我想要使用一个对象多久.

这是我对"泄漏"的理解:

人类定义:如果我在不使用内存时分配了内存,则内存正在泄露.

使用计数的编程定义:在分配内存时,内存正在泄漏,但是没有活动对象对相关对象有保留计数.

编程定义使用辅助功能:当分配的内存无法从程序中的任何位置到达时,内存正在泄漏.

Lou*_*nco 5

第二个块的问题是返回后没有代码运行.我本来希望Xcode警告你(看看并尝试修复你的警告,以及错误)

您对泄漏的理解是正确的.构建和分析可能被愚弄 - 它依赖于遵循的编码约定.如果你偏离了这一点,B&A将不会知道(或者会标记不正确的泄漏).

泄漏检测仪器会在程序中插入代码以检查您的辅助功能定义.它可能会被强制转换所愚弄,但如果你只是做相当简单的分配,分配和发布,我会非常认真地对待它所有的标志,除非你绝对确定它是错误的.

返回分配的对象时,请执行以下操作之一

  1. 在返回它之前调用它自动释放 - 在这种情况下,调用者负责保留它,如果它想要更长时间.在整个callstack退回到调用你的iOS调用之后释放一个自动释放的对象 - 这就是"池被耗尽"的地方 - 你应该在返回iOS之前保留它.

  2. 将您的消息命名为allocSOMETHING或newSOMETHING,不要调用autorelease.在这种情况下,您的消息被理解为返回一个保留计数为1的对象,并且调用者负责释放它(或自动释放它).

如果您执行上述任一操作,Build and Analyze将了解并帮助您做到正确.

编辑:根据评论添加newSOMETHING