在dealloc中释放NSMutableArray会导致应用程序崩溃

时间:2012-10-22 07:03:24

标签: ios memory-management memory-leaks nsmutablearray

我有UIView,其中包含UITableView。此表格由NSMutableArray填充。

我在UIView的initWithFrame:方法中初始化了数组和表。

- (id)initWithFrame:(CGRect)frame
{
  self = [super initWithFrame:frame];
  if (self)
  {
    bookTable = [[UITableView alloc]initWithFrame:CGRectMake(100, 108, 260, 535)];
    bookArray = [[NSMutableArray alloc]init]; //this array will be populated later

    //other codes
  }
  return self;
}

我在dealloc中发布了它们:

- (void)dealloc
{
   [bookTable release];      
   [bookArray release];

   [super dealloc];
}

问题是当应用程序在dealloc崩溃时。它产生错误:[CALayer release]: message sent to deallocated instance 0x82db660

我在我的代码中到处查看,我确信我没有过度发布任何内容。我决定删除[bookArray release]中的dealloc,它就会停止崩溃。我跑了Analyze并没有给我任何潜在的泄漏。

有人可以向我解释为什么在dealloc中释放数组会导致崩溃吗?

注意: 表和数组都是视图的实例变量。

修改 填充数组的代码:

NSString *sql = [NSString stringWithFormat:@"SELECT BookName FROM books WHERE UserID=%d", userId];
booksArray = [sqlite executeQuery:sql];

请注意我使用的是sql包装器。

4 个答案:

答案 0 :(得分:0)

问题在这里,我假设。

booksArray = [sqlite executeQuery:sql];

executeQuery方法可能会返回一个自动释放的NSMutableArray,或类似的内容可能会写在executeQuery

NSMutableArray* tempArray = [NSMutableArray arrayWithCapacity:0];

如果它是这样的,它应该已经处于自动释放模式,因此release方法中没有dealloc

<强>更新

此外,as0sign属性为数组。

@property (nonatomic, retain) NSMutableArray* booksArray;

然后,无论您在何处使用它,请将其用作self.booksArray

self.booksArray = [sqlite executeQuery:sql];

这样,它将是正确的内存管理,然后在dealloc中释放数组。

答案 1 :(得分:0)

这就是问题所在

booksArray = [sqlite executeQuery:sql];

sqlite返回的数组是一个自动释放的对象。您必须保留它或从`dealloc'中删除释放。

booksArray = [[sqlite executeQuery:sql] retain];

由于它是自动释放的对象,因此当系统也尝试release时,以dealloc释放它会导致崩溃。

并且在init方法中删除数组初始化,这是多余的。

答案 2 :(得分:0)

  1. 更改executeQuery方法的退货声明,例如[array autorelease]
  2. booksArray = [sqlite executeQuery:sql];替换为booksArray = [[sqlite executeQuery:sql] retain];
  3. 如果您为property booksArray写了@property(nonatomic, retain) NSMutableArray *bookArray;,那么您可以将{strong>第2步替换为self.bookArray = [sqlite executeQuery:sql];

    您的问题是您从executeQuery方法返回已发布的对象(您在评论中提到了它)。这就是你得到错误的原因

答案 3 :(得分:0)

我建议为booksArray创建一个属性:

@property (nonatomic, retain) NSMutableArray *bookArray;

当您填充它时,请尝试以下代码:

self.bookArray = [NSMutableArray arrayWithArray:[sqlite executeQuery:sql]];

这将创建一个自动释放的返回数组副本,然后由属性“自动”获取。

当然你应该确保通过[sqlite executeQuery:sql]返回的数组是自动释放的。