我仍然在学习内存分配和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()的值)。
答案 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)已经发布。