iphone - 两个 Objective-C 内存管理问题 : Is Leak Detection Always Right? 和为什么 autorelease 工作但不释放?

标签 iphone objective-c memory-management memory-leaks

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

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

    [expressionDescription release];
    return expressionDescription;
}

但是没想到下面会导致内存泄露:

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

    return expressionDescription;
    [expressionDescription release];
}

最终,我的解决方案是改为:

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

    [expressionDescription autorelease];
    return expressionDescription;
}

我明白为什么自动释放会起作用,但是返回值后释放是如何导致泄漏的呢?

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

我意识到开发 Instruments 和 XCode 的构建和分析功能的程序员在这方面比我更有经验,所以现在我假设他们总是对的。但是,我很难理解像 Instruments 这样的程序如何“知道”内存正在泄漏。我认为这应该完全取决于我这个程序员想要使用一个对象多长时间。

这是我对“泄漏”的理解:

人的定义:如果我在不使用的时候分配了内存,就是内存泄漏。

使用计数的编程定义:分配内存时内存正在泄漏,但在相关对象上没有具有保留计数的事件对象。

使用辅助功能的编程定义:当分配的内存无法从我现在在程序中的任何位置访问时,内存就会泄漏。

最佳答案

第二个 block 的问题是返回后没有运行代码。我本以为 Xcode 会就此警告您(查看并尝试修复您的警告和错误)

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

检漏仪将代码插入到您的程序中以检查您的辅助功能定义。它可能会被转换所愚弄,但如果您只是进行相当简单的分配、分配和释放,我会非常认真地对待它标记的所有内容,除非您绝对确定它是错误的。

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

  1. 在返回它之前对其调用 autorelease -- 在这种情况下,如果调用者想要它更长的时间,则调用者负责保留它。在整个调用堆栈展开回调用您的 iOS 调用后,将释放一个自动释放的对象——这就是“池被耗尽”的地方——您应该在返回 iOS 之前保留它。

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

如果您执行其中任一操作,Build and Analyze 将理解并帮助您正确执行。

编辑:根据评论添加新内容

关于iphone - 两个 Objective-C 内存管理问题 : Is Leak Detection Always Right? 和为什么 autorelease 工作但不释放?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4527101/

相关文章:

iphone - 是否可以根据应用程序的捆绑标识符获取应用内购买产品标识符列表

ios - 按钮文字不显示

c - 如何正确释放复合运算中使用的 c 矩阵

iphone - 如何使开关转移到另一个 View Controller ?

iphone - 从具有多个部分的 UITableView 中删除行

objective-c - 缩小 UIScrollView 以专注于某个页面

iphone - iPhone 中的 Dropbox 下载问题

c - 为什么在使用 free() 释放内存时,指针指向的内容没有改变?

java - 我们可以从 java 应用程序内部限制 java 应用程序的内存吗?

iphone - UIActivity 重复调用 'activityViewController'