Reputation:
I have a scrollview. I add a button to this scrollview and release it after.
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];
The application crashes when the view appears on screen, and I try and touch any part of the screen.
If I comment out
[saveButton release];
the application works perfectly.
I thought the retain count of the button would be incremented once I add it to the scrollview so it would be safe for me to release the button.
What's going on here? Is adding something to a scrollview not the same as adding it to the main view like below?
[self.view addSubview:saveButton];
Upvotes: 3
Views: 350
Reputation: 11839
buttonWithType:
is a convenience constructor, so it already creates an autoreleased instance, and there is no need to release the object.
That means the following line of code is an error:
[saveButton release];
You should not send release
, as the instance is already autoreleased.
Check the UIButton
reference for details.
Upvotes: 10
Reputation: 4715
The problem here is that the
[UIButton buttonWithType:UIButtonTypeCustom]
method returns an autoreleased object which is only retained by the autorelease pool (which will release the object at the end of current event queue). That means that you have no ownership over it (it's not retained). Adding it to scroll view bumps the retain count by one, however you immediately destroy it in the next line by sending a release message.
The correct way to do this would be to remove the release call (and you'll be perfectly clear with memory management).
You can read more on iOS memory management here.
Upvotes: 1
Reputation: 3190
There is no alloc/init/new
used here , so this will be autoreleased. If you had something like this UIButton *savebutton = [[UIButton alloc]init];
then you would have to use release like : [saveButton release];
Upvotes: 3
Reputation: 1149
You hav'nt allocate memory to the button object. so how can you release it.
UIButton * saveButton = [UIButton buttonWithType:UIButtonTypeCustom];
You called a static method which itself take care of memory management. That is the only cause of app crashing.
Upvotes: 0
Reputation: 15213
UIButton * saveButton = [UIButton buttonWithType:UIButtonTypeCustom];
This according to the Memory Management Rules this code returns an autoreleased object and you don't have to release it when you finish your job with it. When you add it as a subview of a view, the view you are adding it to is retaining it and you are not responsible for its memory management.
Upvotes: 3