我可以解决的崩溃,但我不明白为什么会发生这种情况

时间:2012-05-21 10:50:00

标签: iphone objective-c ios xcode

我有一个scrollview。我在此滚动视图中添加了一个按钮,然后将其释放。

UIButton * saveButton = [UIButton buttonWithType:UIButtonTypeCustom];
saveButton.frame = CGRectMake(415.0, 473, 80, 38);
saveButton.titleLabel.font = [UIFont fontWithName:@"Heiti TC" size:24];
[saveButton setTitle:@"" forState:UIControlStateNormal];
[saveButton setContentEdgeInsets:UIEdgeInsetsMake(2, 0, 0, 0)];
saveButton.backgroundColor = [UIColor clearColor];
[saveButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal ];
[saveButton setBackgroundImage:[UIImage imageNamed:@"save.png"] forState:UIControlStateNormal];
[saveButton addTarget:self action:@selector(save) forControlEvents:UIControlEventTouchUpInside];
saveButton.hidden = NO;
[self.scrollview addSubview:saveButton];
[saveButton release];

当视图出现在屏幕上时应用程序崩溃,我尝试触摸屏幕的任何部分。

如果我发表评论

[saveButton release];

该应用程序运行良好。

我认为按钮的保留计数会在我添加到滚动视图后增加,所以我可以安全地释放按钮。

这里发生了什么?是否向滚动视图添加内容与将其添加到主视图(如下所示)不同?

[self.view addSubview:saveButton];

5 个答案:

答案 0 :(得分:10)

buttonWithType:是一个便利构造函数,因此它已经创建了一个自动释放的实例,并且不需要释放该对象。

这意味着以下代码行是错误的:

[saveButton release];

您不应发送release,因为该实例已经自动释放。

查看UIButton reference了解详情。

答案 1 :(得分:3)

UIButton * saveButton = [UIButton buttonWithType:UIButtonTypeCustom];

根据Memory Management Rules,此代码返回一个自动释放的对象,当您完成工作时,您不必释放它。当您将其添加为视图的子视图时,您要将其添加到的视图会保留它,并且您不对其内存管理负责。

答案 2 :(得分:3)

这里没有使用alloc/init/new,所以这将是自动释放的。如果您有类似UIButton *savebutton = [[UIButton alloc]init];的内容,则必须使用以下版本:[saveButton release];

答案 3 :(得分:1)

这里的问题是

[UIButton buttonWithType:UIButtonTypeCustom]

方法返回一个自动释放的对象,该对象仅由自动释放池保留(它将在当前事件队列的末尾释放该对象)。这意味着你没有对它的所有权(它没有保留)。将它添加到滚动视图会将保留计数加1,但是您可以通过发送释放消息立即在下一行中销毁它。

执行此操作的正确方法是删除释放调用(对于内存管理,您将非常清楚)。

您可以阅读有关iOS内存管理here的更多信息。

答案 4 :(得分:0)

您没有为按钮对象分配内存。所以你怎么能释放它。

UIButton * saveButton = [UIButton buttonWithType:UIButtonTypeCustom];

您调用了一个静态方法,它本身负责内存管理。 这是应用程序崩溃的唯一原因。