NSMutableArray被破坏了

时间:2009-03-02 10:52:05

标签: iphone

我正在做一个iPhone应用程序,它使用导航控件来浏览一些数据。这个数据存储在一个sqlite数据库中,我有一个获取它的类,并在NSStrings的NSMutableArray中返回它。

问题在于,在导航的第一个屏幕中,一切都运行良好,但在第二个屏幕(推送的另一个视图)中,相同的代码失败,因为NSMutableArray被破坏。在调试器中我可以看到它被正确返回,但是当它使用它时,指针已经损坏并且应用程序崩溃了。

我在所有功能中都设置了断点,但我无法看到任何可能损坏的地方。并且作为第一个使用相同精确代码的视图,甚至访问相同的eact表,工作正常我真的不知道在哪里看。

如果有人想查看我已将其上传到我的网站的代码:http://sachafuentes.com/iBacus.zip

提前致谢。

更新:

问题在于我获取数据的功能,看起来像(这是带有一些伪代码的简化版本)。

-(NSMutableArray *) getPaises {
 NSMutableArray * paises;
 paises = [[NSMutableArray alloc] init];
 while( get new row ) {
  NSString *aPais = get the value;
  [paises addObject:aPais];
  [aPais release];
 }
 return paises;
}

如果我发表评论[aPais发布]一切正常,但对我来说这看起来像是内存泄漏,因为NSString不会被释放。

5 个答案:

答案 0 :(得分:3)

好的,问题在于:

NSString *aPais = [NSString stringWithUTF8String:(char*)sqlite3_column_text(compiledStatement, 0)];

按照惯例,只要您看到allocinit,就需要在某个地方release

按照惯例,只要您使用xWithX:样式方法,就会为您发布生成的对象。

因此,这句话:

[aPais release];

将导致您的方法崩溃,因为对象在它应该被释放之前被释放。只需删除此行,将NSMutableArray实例设置为autorelease - d即可获得更好的结果。

答案 1 :(得分:1)

寻找错误的memory management,这是造成崩溃的最可能原因。我认为你在不应该的地方释放你的对象,因此你在数组中有dangling pointers

UPDATE1

[aPais release]错误,因为您不会在此方法中的任何位置保留它。返回值应始终自动释放。您的代码中retainrelease的数量相同。

(有些人认为retain也可以是alloc init,但我总是尝试使用alloc init autorelease,但这只是风格问题。)

顺便说一句

你应该自动发布你的数组,你只是在[[alloc] init]保留它。

答案 2 :(得分:1)

allocinit必须为release的任何对象 - d当您完成它时,或者您将发生内存泄漏。

由于您将引用传递到getPaises方法的范围之外,您必须自动释放NSMutableArray,否则您将发生内存泄漏:

paises = [[[NSMutableArray alloc] init] autorelease];

请你澄清这里的步骤:

NSString *aPais = get the value;

目前尚不清楚“get the value”中发生了什么,我怀疑这是造成不稳定的一个原因。

答案 3 :(得分:1)

我看到代码是(逐字)

while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
    NSString *aPais = [NSString stringWithUTF8String:
                       (char*)sqlite3_column_text(compiledStatement, 0)];
    [paises addObject:aPais];
    [aPais release];
}

......就像@gs所说的那样。 aPais已自动发布,不应发布。

答案 4 :(得分:0)

您还可以使用便利构造函数来初始化NSMutableArray:

NSMutableArray *paises = [NSMutableArray array];

这相当于:

NSMutableArray *paises = [[[NSMutableArray alloc] init] autorelease];