0

我的 iOS 应用程序中存在内存泄漏,我对 IOS 中的内存管理非常陌生。请建议如何解决以下问题。

泄漏的变量是内容。如果我按照下面代码中显示的方式(目前已被注释掉)释放,该对象仍在泄漏。此外,while 循环将始终执行一次。

if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL) == SQLITE_OK) {
            // We "step" through the results - once for each row.
            while (sqlite3_step(statement) == SQLITE_ROW) {


                content  = [[NSString alloc] initWithUTF8String:
                            (const char *) sqlite3_column_text(statement, 1)];

            }
        }
    }

    detailsArtViewController *det = [[detailsArtViewController alloc] init];

    NSString *decodeString = [self htmlEntityDecode:content];
    //[content release];
4

2 回答 2

2

每个 alloc/init 必须与某个地方的释放或自动释放平衡。我没有看到您的 VC 的任何版本,也没有任何先前值的版本(content如果有的话)。

因此,您的代码存在一些问题:

  • while如果您的循环执行多次,则您没有任何保护措施(实际上,对于根本不执行(SQL 错误或无结果)的情况,您似乎也没有任何保护,但那是另一回事)。这意味着如果你的结果不是你所期望的,你会得到一个泄漏
  • 因此,您应该在将 content 的先前值分配给循环中的新值之前释放它,这样如果 content is not nil 内存将被平衡。这是使用属性而不是 ivars 更安全的原因之一,顺便说一下,见下文。
  • 您的detailsArtViewController 永远不会被释放,因此也可能是您的泄漏源(顺便说一下,类名应该以大写字母开头。遵循命名约定将有助于其他人更好地理解您的代码,并为您节省很多理解符号的麻烦,确保 KVC 工作,等等,所以你也应该尽快采用它)

这里有多个建议,我强烈建议您遵循:

  • 阅读文档遵循内存管理策略。规则非常简单(每个alloc/copy/mutableCopy必须用 / 来平衡release……autorelease这就是您必须知道的全部内容,至少它基本上是最重要的规则)。
  • 我强烈建议使用属性而不是实例变量(如果content是 ivar 而不是本地 var 在你的情况下?)。感谢 Modern Runtime——从 iOS 开始就可以使用——你不需要为你的属性创建实例变量,@synthesize指令会为你做这件事(在与最后一个 Xcode/LLVM 编译器一起发布的 Modern Objective-C 中) ,您甚至都不需要该@synthesize指令)。到处使用属性而不是实例变量(使用self.content代替content将确保调用属性的设置器,因此内存管理正确完成释放先前的值并保留新的值(对于retainproperties),因此您不必担心释放旧值,这与直接使用实例变量相反。
  • 您可以使用 ARC来避免泄漏并避免必须自己做retain/release跳舞。当然,我不建议ARC将其作为“避免学习内存管理的一种方法”:了解内存管理的工作原理仍然非常有用,至少可以避免保留周期和类似的东西,但它会通过避免让事情变得更容易打扰retain/release调用,因此对于初学者来说通常更容易,即使我仍然建议学习内存管理以了解逻辑和微妙之处(ARC也可能出现)。
于 2012-09-12T21:20:53.707 回答
0

迁移到 ARC,您就不必担心这种泄漏。它非常适合初学者。

http://developer.apple.com/library/mac/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html

于 2012-09-12T21:16:05.270 回答