I have an UI button and it works correctly when I pressed.
But if I press the button three times, I get an EXc_BAD_ACCESS error.
I thought I release something in somewhere but I couldn't find the solution.
Could you please help me?
Kind regards.
This is the function when I pressed the button. And in dealloc I release them. When I am tracking, it doesn't give the error in function. I got it after function, but I dont know where the code goes after this function.
- (IBAction) doSomething: (id)sender
{
[self.answerDict replaceObjectAtIndex:currentPageNumber withObject:#"1"];
[self.b setImage:nil forState:UIControlStateNormal];
[self.c setImage:nil forState:UIControlStateNormal];
[self.d setImage:nil forState:UIControlStateNormal];
[self.e setImage:nil forState:UIControlStateNormal];
UIImage *img = [UIImage imageNamed:#"a.jpg"];
[self.a setImage:img forState:UIControlStateNormal];
[img release];
}
UIImage *img = [UIImage imageNamed:#"a.jpg"];
[self.a setImage:img forState:UIControlStateNormal];
[img release];
[img release]; is the problem. You are releasing an object which you dont own. img in this case is auto-released.
Remove [img release]; and see if the crash occurs
I suggest you to comment the code line by line and in that way you will understand what is the purpose of BAD_ACCESS error. At firs close whole code in the doSomething: may be the main reason is in your button ...
Related
well, i'm making an app from a UiWebView example i found. and i needed to add a button but the way this example works is similar to phonegap so i figured out i need to add the button as a subview to the window, so then i got my button and set it up for pressing but when ever i press it my app crashes... can any one help? here is my code snippet:
- (void)webViewDidFinishLoad:(UIWebView *)webView{
myLoadingLabel.hidden = YES;
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[window addSubview:webView];
//my button
UIButton *playButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain];
playButton.frame = CGRectMake(122, 394, 76, 76);
[playButton setTitle:#"Play" forState:UIControlStateNormal];
playButton.backgroundColor = [UIColor clearColor];
[playButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal ];
UIImage *buttonImageNormal = [UIImage imageNamed:#"mic.png"];
UIImage *strechableButtonImageNormal = [buttonImageNormal stretchableImageWithLeftCapWidth:12 topCapHeight:0];
[playButton setBackgroundImage:strechableButtonImageNormal forState:UIControlStateNormal];
UIImage *buttonImagePressed = [UIImage imageNamed:#"mic.png"];
UIImage *strechableButtonImagePressed = [buttonImagePressed stretchableImageWithLeftCapWidth:12 topCapHeight:0];
[playButton setBackgroundImage:strechableButtonImagePressed forState:UIControlStateHighlighted];
[playButton addTarget:self action:#selector(playAction:) forControlEvents:UIControlEventTouchUpInside];
[window addSubview:playButton];
}
-(void)playAction {
NSLog(#"Button Pressed!");
}
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIWebView_ExampleAppDelegate playAction:]:
oh and i know its a long shot, but i need this button outside of the webpage because it needs to start recording audio when clicked, then when clicked again it needs to stop recording and save, run a command with system();, and then put the data gotten from the system command into the uiwebview to be used... so yea if anyone knows some code i would appreciate it greatly, and its a jailbreak app so the system command will be ok. Thanks!!!
You are invoking a method named playAction: but you implement a method named playAction. Mind the missing colon. The crash most likely is related to that issue.
For a quick fix, change
[playButton addTarget:self action:#selector(playAction:) forControlEvents:UIControlEventTouchUpInside];
to
[playButton addTarget:self action:#selector(playAction) forControlEvents:UIControlEventTouchUpInside];
The problem is this:
#selector(playAction:)
vs.
- (void)playAction
The former refers to a method called -playAction: that takes one parameter, but you’ve implemented a method called -playAction that takes no parameters. Drop the colon from the #selector block and it should work.
I have following code and when I call this method, it doesn't change the image of the button although there are images in the resources.
-(void)changeButton:(NSString*)button withURL:(NSString*)url {
timetableURL = url;
UIImage *btnImage;
if ([button isEqual:#"Browser"]) {
btnImage = [UIImage imageNamed:#"browser-button.png"];
[safariBtn addTarget:self action:#selector(onSafariButtonPress:) forControlEvents:UIControlEventTouchUpInside];
}
else if ([button isEqual:#"Timetable"]) {
btnImage = [UIImage imageNamed:#"browser-timetable.png"];
[safariBtn addTarget:self action:#selector(onTimetableButtonPress:) forControlEvents:UIControlEventTouchUpInside];
}
[safariBtn setImage:btnImage forState:UIControlStateNormal];
[btnImage release];
}
UPDATED
FYI: It's a button upside UIToolbar.
Some things that seem to be wrong with your code:
[btnImage release]
You've created that image using autorelease, you are not responsible for its release. This will most likely end up in weird stuff happening, i.e. what you encountered.
Are you sure that btnImage has contents after that if statement? is there a possibility that button is not equal to #"Browser" nor #"Timetable"?
Also, make sure the button is in its normal state.
Cheers
Try This ,
[safariBtn setBackgroundImage:btnImage forState:UIControlStateNormal];
No need to release btnImage ...
i think this should help you...
[safariBtn setImage:[UIImage imageNamed:#"browser-button.png"] forState:UIControlStateNormal];
may be this will help you : set the titles of button where you created it and then control if it equals the title.
[safariBtn setTitle:#"Safari" forState:UIControlStateNormal];
then control
-(void)changeButton:(NSString*)button withURL:(NSString*)url {
timetableURL = url;
UIImage *btnImage;
if ([button titleForState:UIControlStateNormal] isEqualToString:#"Safari"]) {
btnImage = [UIImage imageNamed:#"browser-button.png"];
[safariBtn addTarget:self action:#selector(onSafariButtonPress:) forControlEvents:UIControlEventTouchUpInside];
}
else if ([button titleForState:UIControlStateNormal] isEqualToString:#"Timetable"]) {
btnImage = [UIImage imageNamed:#"browser-timetable.png"];
[safariBtn addTarget:self action:#selector(onTimetableButtonPress:) forControlEvents:UIControlEventTouchUpInside];
}
[safariBtn setImage:btnImage forState:UIControlStateNormal];
[btnImage release];
}
Change
[button isEqual:#"Browser"]
To
[button isEqualToString:#"Browser"]
isEqual is testing for object equality, not string equality.
EDIT: OK, you say your button is inside a toolbar. In this case I assume you have added it as a customview to a UIBarbuttonItem? You need to go through the bar button item and set the image property on the custom view of the bar button item, I think (though I'm not sure) once you've added a button as a custom view, the bar button item makes it's own copy so you are not talking to it any more via safariBtn.
You can access the toolbar items via
for (UIBarButtonItem *barItem in self.toolbar.items)
Assuming this code is in your viewController. Your safariBtn will then be accessible via barItem.customView
I have written this code to see different image states...
UIButton *btnComment = [UIButton buttonWithType:UIButtonTypeCustom];
btnComment.tag=indexPath.row;
[btnComment addTarget:self action:#selector(goToComment:)forControlEvents:UIControlEventTouchDown];
UIImage *img1 = [UIImage imageNamed:#"commentbtndown.png"];
UIImage *img2 = [UIImage imageNamed:#"commentbtnup.png"];
UIImage *img3 = [UIImage imageNamed:#"commentbtnover.png"];
[btnComment setImage:img1 forState:UIControlStateNormal];
[btnComment setImage:img2 forState:UIControlStateHighlighted];
[btnComment setImage:img3 forState:UIControlStateSelected];
[btnComment setImage:img2 forState:(UIControlStateHighlighted+UIControlStateSelected)];
btnComment.frame =CGRectMake(0, 100, 95, 25);
[cell addSubview:btnComment];
[img1 release];
[img2 release];
[img3 release];
but its not working, it is always showing me image 1.
p.s. I have added these images in the table view cell
The problem is that you are creating the UIImage objects with an autorelease method imageNamed, and you are releasing these objects afterwards, which cause your button to have invalid objects and because of that the images will not be displayed
Try removing this lines of code and your button will work
[img1 release];
[img2 release];
[img3 release];
And also, if you want the button to receive the touch events, you will have to add it to the contentView of your cell object, otherwise the button will be shown but you will not be able to tap it.
[cell.contentView addSubview:btnComment]
Well one problem with your code is that you should not be releasing those image variables. imageNamed: returns an autoreleased UIImage. I'm doubt that this is causing your problem, though.
Try using | instead of + for your fourth setImage call.
Another problem with your code is where you add the button to your UITableViewCell. Instead of this:
[cell addSubview:btnComment];
You should add subviews to your cell's contentView:
[cell.contentView addSubview:btnComment];
But I'm also not certain that this may cause your problem...
I have a app that has multiple buttons that are all assigned images in the interface builder. I then change there images during the application. What i want to know how would you is to change the images back to the original image....I did it by the following code but it keeps crashing the app
- (IBAction)resetCards
{
NSString *cardImage = [[NSString alloc] initWithFormat:#"CardBackground.png"];
UIImage *buttonImage = [UIImage imageNamed:cardImage];
[holdCardOne setImage:buttonImage forState:UIControlStateNormal];
[holdCardTwo setImage:buttonImage forState:UIControlStateNormal];
[flopCardOne setImage:buttonImage forState:UIControlStateNormal];
[flopCardTwo setImage:buttonImage forState:UIControlStateNormal];
[flopCardThree setImage:buttonImage forState:UIControlStateNormal];
[turnCard setImage:buttonImage forState:UIControlStateNormal];
[riverCard setImage:buttonImage forState:UIControlStateNormal];
[cardImage release];
[buttonImage release];
}
Don't call [buttonImage release] -- it is being autoreleased.
Usually only call release if you call alloc, copy, or retain. Always check the documentation for a message that returns an object if you are unsure, but normal Objective-C process is to return objects that autorelease.
In addition to Lou's answer, why not use:
UIImage *buttonImage = [UIImage imageNamed:#"cardBackground.png"];
Instead of creating an NSString?
I added an image to button
UIImage* deleteImage = [UIImage imageNamed:#"Delete.png"];
CGRect imageFrame=CGRectMake(-4,-4, 310, 55);
[btn setFrame:imageFrame];
btn.backgroundColor=[UIColor clearColor];
[btn setBackgroundImage:deleteImage forState:UIControlStateNormal];
[btn setTitle:#"Delete" forState:UIControlStateNormal];
[btn addTarget:self action:#selector(editDeleteAction) forControlEvents:UIControlEventTouchUpInside];
[elementView addSubview:btn];
[deleteImage release];// do we need to release the image here
If I release here its working fine but in object allocations no.of image count is increasing.
If you create an image with the imageNamed: message you don't have to release it, because you get an autoreleased image back.
Only if you create the image with one of the init...: messages you have to release it later on.
"imageNamed:" method gives an autoreleased object, so you don't have to release object.
FYI: "imageNamed:" method uses an internal cache (you may face memory warning if imageNamed: method used extensively). It is better to remove cache on receiving warnings.
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
[[ImageCache sharedImageCache] removeAllImagesInMemory];
}
Go through this guide http://akosma.com/2009/01/28/10-iphone-memory-management-tips/