释放指针会导致程序崩溃,即使未使用该变量也是如此

时间:2011-08-03 15:32:54

标签: objective-c ios memory-management memory-leaks

我仍然在学习内存分配和Objective-C(我第一次使用Leaks运行时充其量只是不合适)。这是一个当前的问题,我希望每个人都能理解它,我使用了一些伪代码,但我不相信我已经遗漏了任何东西。

我为某些数据库设置了一个Row Class,我们将使用它:

@interface Row : NSObject {
    int rowID;
NSString *firstName;
NSString *lastName;
}


我的数据库类中有一个getRow函数,如下所示:

-(Row *) getRow 
{
  rowPlaceholder = [[Row alloc] init];    
       ...
  rowPlaceholder.rowID = column1;
  rowPlaceholder.firstName = column2;
  rowPlaceholder.lastName = column3;
       ...
    return [rowPlaceholder autorelease]; //<-----Problem is happening here
}


现在在我的ViewController中,我有两个对这种情况很重要的函数:

-(void) viewWillAppear:(BOOL)animated{
currentRow = [[Row alloc] init];
currentRow = getRow;
firstNamelabel.text = currentRow.firstName;
}


第二个功能是获取第二个单词的按钮:

-(IBAction)btnLastName:(id)sender{
lastNamelabel.text = currentRow.lastName; //<---Crashes the program
}


所以,正如你所看到的,使用currentRow会导致程序崩溃,而我无法理解的是,如果我不释放rowPlaceholder,程序运行正常。在这一点上,为什么currentRow关心来自另一个函数的数据,因为它已经拥有它想要的东西(来自getRow()的值)。

3 个答案:

答案 0 :(得分:2)

这里发生了什么?

currentRow = [[Row alloc] init];
currentRow = getRow;

你创建一行,然后用...覆盖它。我甚至不知道在这种情况下getRow是什么。没有警告就没有办法编译。无论如何,尝试使用:

currentRow = [[self getRow] retain];

(虽然为了惯例,你应该只调用row方法。)

如果没有看到getRow方法或Row课程的其余部分,我就无法确定为什么问题会在那里发生。

答案 1 :(得分:1)

autorelease表示相关对象将自动释放。当发生这种情况与自动释放池被清空时相关联,但是对于默认情况,当UI“出现空气”时 - 当您的调用链返回到UI系统代码时。如果你要保持“跨越”这样的返回UI系统代码的东西,你需要明确地保留它。一般来说,将其作为保留属性是执行此操作的最佳方法(当然,您需要在dealloc方法中清除/释放该属性)。

[为什么这样做:]

currentRow = [[Row alloc] init];
currentRow = getRow;

答案 2 :(得分:0)

当你分配并初始化rowPlaceholder然后将其作为自动释放时返回时,这意味着它有效地准备好被内存管理清理,除非其他一些对象保留它。

在行中:

currentRow=getRow

您正在获取指向getRow返回的对象的指针的副本,但似乎没有保留它。 (并且getRow在返回之前自动释放它。)

如果currentRow是您的类的属性,那么您需要将其称为this.currentRow以确保调用accessor方法(并且必须将其声明为retain属性)。如果它没有被声明为属性并且只是你的类的一个属性,那么你需要手动保留它。

第一次引用currentRow.firstName是正常的,因为当前执行线程没有失去控制权,因此自动释放池尚未清理此内存。

但是一旦你的线程失去控制并给内存管理一个机会来清理它,当你回到btnLastName方法时,currentRow指向的内存(这是指向rowPlaceHolder中分配的原始内存的指针= [ [row alloc] init] call)已经发布。