Memory leak causing app to crash - iphone

My app gives a low memory crash on the device and not on the simulator.I used Instruments and i think that the problem lies in the following part
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setBackgroundImage:[UIImage imageNamed:#"gembtnblu.png"] forState:UIControlStateNormal];<br>
button.frame = CGRectMake(0, 0, TOOLBAR_BUTTON_WIDTH , TOOLBAR_BUTTON_HEIGHT);<br>
[button setTitle:[NSString stringWithFormat:#"%c",choice] forState:UIControlStateNormal];<br>
[button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[button addTarget:self action:#selector(ChoiceButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
[button setTag:choice];
UIBarButtonItem *customBarItem = [[UIBarButtonItem alloc] initWithCustomView:button];
//Add button to the array
[tempItems addObject:customBarItem];
if (isReviewing == TRUE) {
customBarItem.customView.userInteractionEnabled=FALSE;
}
//release buttons
[customBarItem release];
numberOfChoices++;
But im not able to spot the problem.Please help guuys, i have beeen stuck at this for days now
heres some more code
NSArray *items=[[NSArray alloc] initWithArray:(NSArray *)tempItems];
[tempItems release];
//add array of buttons to toolbar
[toolbar setItems:items animated:YES];
[self.view addSubview:toolbar];
the static analyser says that theres a potential leak with 'items' array.But if i put in a release statement, the app crashes

Did you release the toolbar after adding it as a subview? If you did not, and are not releasing the toolbar in the dealloc, there's your leak.

Is the image you're creating large? It could be that you're loading a huge message into memory and not releasing it.
I'd recommend running the static analyzer on this code (Build and Analyze), the errors should help you understand where you aren't releasing things that you should be.

The snippet of source code you posted does not contain memory management errors. I am assuming here that the image you load is small, since this is for a button. Note that imageNamed: caches the image but assuming the image is small this is not a problem.
Either the problem lies somewhere else in the code, or on your device you have too much applications open simultaneously. Beware of applications running in background: these still are eating memory. Try closing all of the applications and running again yours on the device. See if you experience exactly the same behavior when executing the same code snippet.

You may not be releasing old buttons and lists before allocating new ones. Perhaps you should reuse the old buttons instead of creating new similar ones.

Related

UIButton Bug? (Xcode Version 4.6 (4H127))

1st: Xcode Version 4.6 (4H127), simulator 6.1
So... i do the following.
My button (inherited from UIButton) loaded from nib. Then i've set image to it for UIControlStateNormal.
I've got something like this:
After that i need to nullify it:
[button setImage:nil forState:UIControlStateNormal];
then i see this:
Check diffs:
So the title layouted right, but the image still there...
Also, if i do following:
[button setImage:[UIImage new] forState:UIControlStateNormal];
I get result like the second one, but without an image (as expected, but not fully, without layouting):
I am really interested in what is happening here?
Its really interesting, mb Apple broke something? Or i've just doing all wrong? But i've done it many times(setting image->nil), all worked Okay.
Thank you for reading :) I would appreciate for any help.
I have wrote a sample code regarding this.
Your both calls worked me fine
[self.myCustomButton setImage:nil forState:UIControlStateNormal];
[self.myCustomButton setImage:[UIImage new] forState:UIControlStateNormal];
I think, you may set the BackGroundImage instead of image.
Sample Methods
-(IBAction)removeImage:(id)sender{
[self.myCustomButton setImage:nil forState:UIControlStateNormal];
//[self.myCustomButton setImage:[UIImage new] forState:UIControlStateNormal];
}
-(IBAction)setImage:(id)sender{
[self.myCustomButton setImage:[UIImage imageNamed:#"Button_Disable.jpg"] forState:UIControlStateNormal];
}
This thing was here:
My subclass of UIButton overrides -layoutSubviews, where setting imageView.hidden using some criteria.
So, if hidden property was YES, when i've calling setImage:forState - this bug happened.
My fix was next:
I just start using alpha property instead of hidden. (I know that is dirty, but this is the fastest way i've found)

Strange behaviour of simulator & device when adding rightBarButtonItems to a UINavigationItem

In my application I am added two button at right of a UINavigationItem, its working fine on simulator, but when I testing it on device its gives me error of SIGABRT, along with unrecognized selector sent to NSArray. I tried to add one button at right side, it was added successfully, and works fine on device as well. Here my question is, whats the problem?
I am adding right buttons using following code,
NSArray *buttons=[[NSArray alloc] initWithObjects:btnOne,btnTwo,nil]];
myNavItem.rightBarButtonItems=buttons; //Error on device, but works fine on simulator.
Please, point me what is I doing wrong?
Thanks!
It appears that myNavItem is not an instance of UINavigationItem, but rather an instance of NSArray (which does not support setRightBarButtonItems). Could you show us more lines concerning myNavItem?
My suspicion is that myNavItem did not correctly retain the navigation item that it was originally pointing to. And that it points to an NSArray now by coincidence. This error might not occur in a debug setting if all objects are retained indefinitely for better logging.
If this code runs from an instance of a view controller try to use this line instead:
self.navigationItem.rightBarButtonItems = buttons;
On iOS prior to version 5: if you receive unrecognized selector sent to NSArray logs there is something wrong with your memory management. The log should read unrecognized selector sent to UINavigationItem on iOS prior to iOS 5.
Once the memory issue is fixed you should use a UIBarButtonItem with a custom view containing two UIButtons.
try adding these buttons to a UIBarButtonItem and add UIBarButtonItem to myNavItem like myNavItem.rightBarButtonItem = barButtonItem;
Your first line
NSArray *buttons=[[NSArray alloc] initWithObjects:btnOne,btnTwo,nil]];
has an extra right bracket at the end. Not sure if this would cause that error but it should cause some error.
You can use the UISegmentedControl. Check the UICatalog code sample to check its usage in the navigation bar.
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc]initWithItems:[NSArray arrayWithObjects:btn1,btn2,nil]];
[segmentedControl addTarget:self action:#selector(segmentAction:) forControlEvents:UIControlEventValueChanged];
segmentedControl.frame = CGRectMake(0, 0, 90, 35);
segmentedControl.segmentedControlStyle=UISegmentedControlStyleBar;
segmentedControl.momentary = YES;
UIBarButtonItem *segmentBarItem = [[UIBarButtonItem alloc] initWithCustomView:segmentedControl];
[segmentedControl release];
self.navigationItem.rightBarButtonItem = segmentBarItem;
[segmentBarItem release];
}
This is the best way of adding as many number of buttons in your bar as you desire.Hope it gonna help u.
Thanks :)

UIButton setImage not working

I'm losing my mind over this one. I have UIButton connected as Outlet. I want to change it's image. In the viewDidLoad function, I try to set the image like so:
[button1 setImage:[UIImage imageNamed:#"house.png"] forState:UIControlStateNormal];
Nothing happens. However, if I use ImagePicker, it somehow works. In the ImagePickers function "didFinishPickingImage", I repeat the exactly same command as above for setting image and it works, the image is displayed normally.
I've been thinking that maybe the button's image is not refreshing itself, but trying to call [button1 setNeedsDisplay], or [button1.imageView setNeedsDisplay] or even [button1.imageView.image setNeedsDisplay] does nothing.
Does anyone have any idea about this? I've wasted two hours by now and I'm really getting frustrated, because I'm certain that the reason must be so stupid it's unbelivable.
Please check your button type.
If your button type is "System" you should change it to "Custom"
Two things to do here:
#1, change your code to:
[button1 setImage:[UIImage imageNamed:#"house.png"] forState:UIControlStateNormal];
and #2
make sure your UIImage returns a valid image.
In other words,
UIImage * imageToSet = [UIImage imageNamed: #"house.png"];
if(imageToSet)
{
[button1 setImage:[UIImage imageNamed:#"house.png"] forState:UIControlStateNormal];
} else {
// if you see this line in your console, then you know where to look for a problem
NSLog( #"why is my image object nil?");
}
For anyone who will find themselves in a similar situation; I was using the mentioned button inside a custom cell for table view. However, the cells aren't loaded right away (i.e. inside viewDidLoad/viewWillAppear etc.), but inside the tableView:cellForRowAtIndexPath function. All my button variables were nil at that point. My solution was to load the image after the cell has been created and it has worked straight away afterwards.
Here are a couple additional notes. UIButton setImage: forState: is the correct method:
[button1 setImage:[UIImage imageNamed:#"house.png"] forState:UIControlStateNormal];
imageNamed is a great convenience method for grabbing the image, but make sure it returns an object. Forgetting to include the image file in the current target gets me all of the time.
[UIImage imageNamed:#"house.png"]
You also don't need the extension. The SDK works this out.
[UIImage imageNamed:#"house"]
And even though UIControlState is a bit mask, you cannot OR the values together. This does not not not work and I must must must remember this because it gets me every time I use the call.
// NO NO NO
[button1 setImage:[UIImage imageNamed:#"house"] forState:UIControlStateNormal|UIControlStateSelected];
// YES
[button1 setImage:[UIImage imageNamed:#"house"] forState:UIControlStateNormal];
[button1 setImage:[UIImage imageNamed:#"house"] forState:UIControlStateSelected];
Was getting the same problem when UIbutton was in UITableViewCell.
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:[UIImage imageNamed:#"detail.png"] forState:UIControlStateNormal];
should work in UITableViewCell
Glad to know that the problem is solved but none of the answers actually addresses the problem.
Generally, if the code is correct, then the error shifts from "syntax error" to the "logical error" category. There is no definite guide to handle it but here is a small checklist that can help anyone to troubleshoot their code.
1) The IBOutlet is not connected or renamed.
2) Make sure that the UIButton type is custom.
3) The image is set (more than once), somewhere else in the code.
4) You are trying to set the Image through any sync method which is not using the main thread. (There are several threads on that alone).
5) If you are nesting the images as subviews, make sure the problem isn't with their parent view.
6) If it is appearing in Simulator but not in the device, It's a lettercase (Uppercase, lowercase difference in the code and the filename.
7) Modern simulators works with very low GPU memory on older machines. You can tweak the simlator options to make it appear. E.g (Command + Right Arrow) twice to change the simulator orientation and your changes will appear.
There are few other but common pitfalls where developers usually overlook
1) The image doesn't exist OR you are making a spelling mistake.
2) The filetype is different than mentioned. (JPG, PNG).
Last thing you'll want to check - make sure you're setting the image on the main thread! Just ran into an issue where I was setting a button image in a callback from ALAssetLibrary (fetching images from photo library). The image wouldn't update until I tapped the button. Turns out the callback was happening off main...
for those having issues with system images not appearing, just use systemName: instead of named
if let starImg = UIImage(systemName: "star.fill") {
button.setImage(starImg, for: .normal)
}
It's for ios13 and later...
For me it was to move the line:
[button1 setImage:[UIImage imageNamed:#"house.png"] forState:UIControlStateNormal];
from awakeFromNib method
to viewDidLoad method
I guess,
don't create like this
UIButton *nextButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
by this create method ,UIButton is create by use default type,so your background image is not work.
try this,
UIButton *nextButton = [[UIButton alloc] initWithFrame:CGRectMake(9, 154, 300, 48)];
or other,except buttonWithType
This is happening because the state of the Button doesn't stays selected once clicked by default.
I solved it by making an IBaction on that button click and toggling the selected state.
-(IBAction) checkButtonClicked:(id)sender{
checkButton.selected = !checkButton.selected;
}
In my case, it is drawn by custom animation code and not set by the image, so it doesn't work by setting any image, it has to change the animation code.
With images, you have to import them into the project not as references but as copies. So when you go to add files to project, choose "Create groups" instead of "Create folder references". Also make sure "Copy items if needed" is checked.
This is confusing because importing as references works when you are using images as textures (e.g. for Sprites). However, it doesn't work when you want to use images for buttons (e.g. for using image name in [UIImage imageNamed:#"house.png"]
I faced this same issue of the image not being shown on the UIButton.
I had to change this line -
myButton.setImage(<my_UIImage_object>, for: [.normal, .focused])
to this -
myButton.setImage(<my_UIImage_object>, for: .normal)

specially indicating or highlighting a toolbar button when a note is added in iphone

In my app i have an option for adding notes to particular tips.the button for adding notes is at the top.So i want to highlight that particular button when a notes is added.If a Tip has a note attached the notes icon should light up / glow (somehow look different), so that it can quickly identify this tip has a note attached.How can i implement this one.Is it possible.Can any one Please help me.Thanks in advance
We used some special button in tool bar in an application. We make it following way.
UIButton* btnInfo = [UIButton buttonWithType:UIButtonTypeInfoLight];
[btnInfo addTarget:self action:#selector(verInfoBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *modalButton = [[UIBarButtonItem alloc] initWithCustomView:btnInfo];
Here main point is to use [[UIBarButtonItem alloc] initWithCustomView:btnInfo]; method.
Check if it can be helpful...

How set image on slider?

I want to use slider control for above image. When user slide then category tab become highlighted and all delighted. So how I use slider controller so that i can get this functionality? How use slider control for that?
The simplest solution would be to render a UIImage behind the control to represent the track. The thumbknob can be changed with:
[mySlider setThumbImage:[UIImage imageNamed:#"thumb_image.png"] forState:UIControlStateNormal];
A side-effect of this is that the track isn't rendered unless you provide your own. This, combined with the UIImage, provide you with a custom UISlider without you having to subclass anything.
The control you are showing is a segment control and you can set the image by using this piece of code
UISegmentedControl* offlineSegment=[[UISegmentedControl alloc] initWithItems:[[[NSMutableArray alloc] initWithObjects:#"ON",#"OFF",nil] autorelease]];
[offlineSegment setFrame:CGRectMake(210,50,90,30)];
offlineSegment.tintColor=[UIColor greenColor];
offlineSegment.selectedSegmentIndex=0;
offlineSegment.segmentedControlStyle=UISegmentedControlStyleBezeled;
[locationSegment setImage:[UIImage imageNamed:#"onSelected.png"] forSegmentAtIndex:0];
[locationSegment setImage:[UIImage imageNamed:#"off.png"] forSegmentAtIndex:1];
[offlineSegment addTarget:self action:#selector(offlineSetting:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:offlineSegment];
[offlineSegment release];
Hope this will help you
I am not sure if this will answer your question or not but I have seen this project of github that looks someWhat like this
https://github.com/samvermette/SVSegmentedControl