我有一个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];
答案 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];
您调用了一个静态方法,它本身负责内存管理。 这是应用程序崩溃的唯一原因。