3

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

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];
4

5 回答 5

10

buttonWithType:是一个方便的构造函数,所以它已经创建了一个自动释放的实例,不需要释放对象。

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

[saveButton release];

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

检查UIButton参考以获取详细信息。

于 2012-05-21T10:52:11.137 回答
3
UIButton * saveButton = [UIButton buttonWithType:UIButtonTypeCustom];

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

于 2012-05-21T10:54:06.740 回答
3

这里没有alloc/init/new用到,所以会自动发布。如果你有这样的东西,UIButton *savebutton = [[UIButton alloc]init];那么你将不得不使用发布,如:[saveButton release];

于 2012-05-21T10:59:50.210 回答
1

这里的问题是

[UIButton buttonWithType:UIButtonTypeCustom]

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

执行此操作的正确方法是删除发布调用(您将完全清楚内存管理)。

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

于 2012-05-21T10:54:49.103 回答
0

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

UIButton * saveButton = [UIButton buttonWithType:UIButtonTypeCustom];

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

于 2012-05-21T10:58:34.003 回答