[UIImage retain]: message sent to deallocated instance - objective-c

We created button in the init method and we created two Uiimage objects and created Boolean
if(!isHint)
{
[hintBtn setImage:hintBtnImage forState:UIControlStateNormal];
}
else
{
[hintBtn setImage:hintBtnImagex forState:UIControlStateNormal];
}
hintBtn =[[UIButton alloc]initWithFrame:CGRectMake(794, 144, hintBtnImage.size.width, hintBtnImage.size.height)];
[hintBtn setImage:hintBtnImage forState:UIControlStateNormal];
[hintBtn addTarget:self action:#selector(showHint) forControlEvents:UIControlEventTouchUpInside];
When ever user taps the tableview cell we changes the boolean variable and we set the image .like the below code
if(wrongx==1)
{
NSLog(#"the wrong x is %i",wrongx);
isHint = NO;
[hintBtn setImage:hintBtnImage forState:UIControlStateNormal];
}
But when i tap the application first time it is working but second time i am getting the below error
[UIImage retain]: message sent to deallocated instance
Plz reply to my post.Thanks in advance

where you allocated "hintBtnImage" object.I think your trying to access the "hintBtnImage" withoout allocating.
hintBtn =[[UIButton alloc]initWithFrame:CGRectMake(794, 144, hintBtnImage.size.width, hintBtnImage.size.height)];
small code modification needed ,its not related to solve your problem,above line should be like this
hintBtn =[[UIButton alloc]initWithFrame:CGRectMake(794, 144, hintBtnImage.size.width, hintBtnImage.size.height)];
if(!isHint)
{
[hintBtn setImage:hintBtnImage forState:UIControlStateNormal];
}
else
{
[hintBtn setImage:hintBtnImagex forState:UIControlStateNormal];
}

Related

Unrecognized Selector sent to Instance in another class

I've been trying to figure out something that might be obvious and I'm missing the point or losing it. Is something wrong with my toggleStormButtons function that XCode isn't seeing it?
In my main class I have the following to call a function in another class:
STopLeftMenu *mTopLeft = [[STopLeftMenu alloc]init];
[mTopLeft drawStormToggleButton];
Then in the other class I have 2 functions:
- (void)toggleStormButtons{
[UIButton animateWithDuration:0.50 animations:^{
if (stormToggleBtn.transform.tx == 0){
[stormToggleBtn setTransform:CGAffineTransformMakeTranslation(307, 0)];
UIImage* hideButtonImg = [UIImage imageNamed:#"aiga_right_arrow_mod_hide_resize.png"];
[stormToggleBtn setBackgroundImage:hideButtonImg forState:UIControlStateNormal];
}
else{
[stormToggleBtn setTransform:CGAffineTransformMakeTranslation(0, 0)];
UIImage* showButtonImg = [UIImage imageNamed:#"aiga_right_arrow_mod_show_resize.png"];
[stormToggleBtn setBackgroundImage:showButtonImg forState:UIControlStateNormal];
}
}];
for(UIView* storm in stormButtonSaves){
[UIView animateWithDuration:0.50 animations:^{
if (storm.transform.tx == 0){
[storm setTransform:CGAffineTransformMakeTranslation(307, 0)];
storm.alpha = .65;
}
else{
[storm setTransform:CGAffineTransformMakeTranslation(0, 0)];
storm.alpha = 0;
}
}];
}
}
- (void)drawStormToggleButton{
//Storm Pullout Toggle Button
UIImage *buttonImageNormal = [UIImage imageNamed:#"aiga_right_arrow_mod_show_resize.png"];
stormToggleBtn = [[UIButton alloc] initWithFrame:CGRectMake(10, 10, 65, 75) ];
[stormToggleBtn setBackgroundImage:buttonImageNormal forState:UIControlStateNormal];
stormToggleBtn.backgroundColor = [UIColor clearColor];
stormToggleBtn.alpha = 0.5;
[stormToggleBtn addTarget:self action:#selector(toggleStormButtons) forControlEvents:UIControlEventTouchUpInside];
[viewsToRemove addObject:stormToggleBtn];
[mv addSubview:stormToggleBtn];
}
I seem to be getting an unrecognized selector message:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSMallocBlock__ toggleStormButtons]: unrecognized selector sent to instance 0x7bc9ca0'
*** First throw call stack:
(0x1b9e012 0x1966e7e 0x1c294bd 0x1b8dbbc 0x1b8d94e 0x197a705 0x8ae2c0 0x8ae258 0x96f021 0x96f57f 0x96e6e8 0x8ddcef 0x8ddf02 0x8bbd4a 0x8ad698 0x2599df9 0x2599ad0 0x1b13bf5 0x1b13962 0x1b44bb6 0x1b43f44 0x1b43e1b 0x25987e3 0x2598668 0x8aaffc 0x2285 0x2185)
libc++abi.dylib: terminate called throwing an exception
It sounds like your STopLeftMenu is being deallocated too early. The button does not retain its target, so you'll need to keep this object around as long as it needs to respond to the button's messages. If you're not sure how the object is getting deallocated, try debugging with Instruments.
I don't see anything wrong with the code you have shown. I tried it in an existing app of mine and while I had to a) declare a UIButton local variable, b) change the image used for the button and c) comment out the stuff in toggleStormButtons, the method was called every time I tapped the button, no problems.
You don't show your storage for the button. Are you using ARC? Is the button strong? If ARC it should be strong. If not ARC and you are not using a property to assign with a retain, that could cause problems.
What does viewsToRemove do? Looks like an array but it could be something else.
Why don't you use + buttonWithType: and set the frame later?

UIButton calling selector crashes the app

In my app I've got a button which is an instance variable declared in the .h file already.
Now after allocating it an assigning at target to it and actually pressing the button, the app crashes giving me following output in the debugger:
-[__NSCFString handleActionSheet:]: unrecognized selector sent to instance 0x9090330
2012-05-04 17:51:02.646 financeAppV2[2595:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString handleActionSheet:]: unrecognized selector sent to instance 0x9090330'
*** First throw call stack:
(0x13d1022 0x1562cd6 0x13d2cbd 0x1337ed0 0x1337cb2 0x13d2e99 0x1e14e 0x1e0e6 0xc4ade 0xc4fa7 0xc3d8a 0x2dfa1a 0x13a599e 0x133c640 0x13084c6 0x1307d84 0x1307c9b 0x12ba7d8 0x12ba88a 0x1b626 0x29dd 0x2945)
terminate called throwing an exceptionCurrent language: auto; currently objective-c
My code looks like following:
saveButton=[UIButton buttonWithType:UIButtonTypeCustom];
[saveButton setBackgroundImage:[UIImage imageNamed:#"intervalbutton"] forState:UIControlStateNormal];
[saveButton setBackgroundImage:[UIImage imageNamed:#"intervalbuttonpressed"] forState:UIControlStateHighlighted];
saveButton.alpha=.8;
saveButton.frame= frame;
UILabel* label=[[UILabel alloc]initWithFrame:CGRectMake(0, 2, saveButton.frame.size.width, 21)];
[saveButton addSubview:label];
[saveButton addTarget:self action:#selector(handleActionSheet:) forControlEvents:UIControlEventTouchDown];
[self.view addSubview:saveButton];
-(void)handleActionSheet:(id)sender{
NSLog(#"working");
}
Any ideas why the app could be crashing?
Without seeing the rest of your code it's difficult to be specific, but self is not correctly being retained.
You set up your button correctly (as far as I can see) and point the target to self. Unfortunately, by the time you press the button self has gone out of scope and the same memory is used by an NSString. iOS gets surprised when you send a string the handleActionSheet: message.
You're sending a message named initAllIVars: to an __NSCFString object (likely an NSString).
Do a search for that message and try to figure out why the object receiving the message is an NSString.
Just tested your code and it works. Maybe the frame it's not properly set
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIButton *saveButton = [[UIButton alloc] init];
saveButton=[UIButton buttonWithType:UIButtonTypeCustom];
[saveButton setBackgroundImage:[UIImage imageNamed:#"intervalbutton"] forState:UIControlStateNormal];
[saveButton setBackgroundImage:[UIImage imageNamed:#"intervalbuttonpressed"] forState:UIControlStateHighlighted];
saveButton.alpha=.8;
saveButton.frame= CGRectMake(5, 5, 200, 40);
UILabel* label=[[UILabel alloc]initWithFrame:CGRectMake(0, 2, saveButton.frame.size.width, 21)];
label.text = #"Hello";
[saveButton addSubview:label];
[saveButton addTarget:self action:#selector(handleActionSheet:) forControlEvents:UIControlEventTouchDown];
[self.view addSubview:saveButton];
}
-(void)handleActionSheet:(id)sender{
NSLog(#"working");
}

Selector is not called

I can't understand why the selector is not called.
//EDITED
[self.scrollView setContentSize:CGSizeMake(320, 600)];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btn addTarget:self
action:#selector(validateTextFields:)
forControlEvents:UIControlEventTouchUpInside];
[btn setTitle:#"Продължи" forState:UIControlStateNormal];
btn.frame = CGRectMake(55, 580, 210, 50);
[self.scrollView addSubview:btn];
-(IBAction)validateTextFields:sender
{
NSLog(#"Called");
}
When I touch the button "Called" is not logged in console. If I change UIControlEventTouchUpInside to UIControlEventTouchDown validateTextFields method is executed.
You are adding a button on UIScrollView, this might be creating problem. Please check this question: iPhone: adding button to scrollview makes button inaccessible to interaction. It may be helpful.
The type for action should be
- (IBAction)validateTextFileds:(id)sender
{
// do your stuff
}
and your #selector parameter in addTarget should look like this: #selector(validateTextFields:)
try this:
[addContact addTarget:self action:#selector(buttonPressed:)forControlEvents:UIControlEventTouchUpInside];
-(IBAction)buttonPressed:(id)sender{
}

Is it Possible to Change Action For UIButton?

I am trying to change Action For the UIButton in ios applicatio. I did Following Code
button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self action:#selector(aMethodShow:) forControlEvents:UIControlEventTouchDown];
[button setTitle:#"Show View" forState:UIControlStateNormal];
button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
[view addSubview:button];
In particular Section I want to change Action for this Button .So i did this
[button addTarget:self action:#selector(aMethodHide:) forControlEvents:UIControlEventTouchDown];
[button setTitle:#"Hide View" forState:UIControlStateNormal];
Unfortunately This code note Working?
I suggest before adding new target, first invoke removeTarget on UIbutton object then add new target with other action.
I think it will help you
[yourButton removeTarget:nil
action:NULL
forControlEvents:UIControlEventAllEvents];
[yourButton addTarget:self
action:#selector(yourAction:)
forControlEvents:UIControlEventTouchUpInside];
You can use same action target instead of using two target. In one target you have to differentiate like below
-(void)btnAction
{
if(target1)
{
// code for target 1
}
else
{
// code for target 2
}
}
Here target1 is BOOL value which value first set to be YES. And change its value NO whenever you want to perform target 2 code.
I hope this will helps You.
I made an app recently and i had the same situation, but i found another way to solve it so i decided to share my solution with people who may be in the same situation.
I'll try to explain what i did with the context of this question:
I added a tag to the button and i associated it with one of the functions that button needs to call (aMethodShow: for example).
button always call the same function (callSpecificFunc: for example). What callSpecificFunc: does is call either function aMethodShow: or aMethodHide according with the current button tag.
In the particular section in which the button needs to call a different function, i only change the tag of button.
Something like this:
NSInteger tagOne = 1000; //tag associated with 'aMethodShow' func
NSInteger tagTwo = 1001; //tag associated with 'aMethodHide' func
button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self action:#selector(callSpecificFunc:) forControlEvents:UIControlEventTouchDown];
[button setTitle:#"Show View" forState:UIControlStateNormal];
button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
[view addSubview:button];
...
// in some part of code, if we want to call 'aMethodShow' function,
// we set the button's tag like this
button.tag = tagOne
...
//Now, if we want to call 'aMethodHide', just change the button's tag
button.tag = tagTwo
...
-(void) callSpecificFunc:(UIButton*)sender
{
NSInteger tagOne = 1000;
NSInteger tagTwo = 1001;
if([sender tag] == tagOne){
//do whatever 'aMethodShow' does
}else {
//do whatever 'aMethodHide' does
}
}
Of course it could be applied for more than 2 functions :)

UIButton created runtime in a loop, now I need a specific function depending on the button touched

I am creating some buttons and putting them inside a UIScrollView like this:
int i = 0;
while (i != numberOfButtons ) {
int updatetY = 160*i;
CGRect buttonFrame = CGRectMake(updatetY, 0, 160, 60);
UIButton *button = [[UIButton alloc] initWithFrame:buttonFrame];
UIImage *buttonImage = [UIImage imageNamed:#"bg.png"];
[button setBackgroundImage:buttonImage forState:UIControlStateNormal];
[button setTitle:[buttonsArray objectAtIndex:i] forState:UIControlStateNormal];
[button addTarget:self action:#selector(MYPROBLEM) forControlEvents:UIControlEventTouchUpInside];
[menuScrollView addSubview:button];
i++;
}
Now I need to build a method to capture which button is being touched, and run a specific bunch of code (see (MYPROBLEM).
Anybody knows what I can do to "trace" which button is being touched and then run a specific function?
something like:
-(void) buttonfunction
{
case ...
doThis
case...
doThat
}
thanks in advance.
You need to use the tag property of the uibutton control. It's a numeric id for the button. You can set a tag on the button based on the i variable in your loop, for instance:
button.tag=i;
Then in your button's action message, you would simply add the id of the button as a parameter and check its tag like so:
-(void) buttonFunction:(id)sender {
switch (sender.tag)
{
//code goes here
}
}
Hope this helps.