I encountered a weird behavior in memory just by displaying the default keyboard.
I've just created a project with an .xib file for testing purposes.
This .xib file has an UITextField element in it and it's connected in the .h via:
#property(nonatomic, retain) IBOutlet UITextField *sometext;
The .m has no changes but:
#synthesize sometext;
- (void)viewDidAppear:(BOOL)animated {
[someText becomeFirstResponder];
}
As you see it's very very simple.
The problem is that once the keyboard is shown, the memory allocated for it NEVER goes down.
I've tested this scenario in another project with the only difference of having two .xib files.
Standar pushViewController and popViewController calls are made. Instruments show an increase of 600kb in memory allocations [which are a lot more in the actual iPhone device].
All in all, hehehe. My question is:
How do I release the memory allocated for the keyboard?.
You don't. Is it a leak? If you are just looking at the Allocations, don't expect it to go back down.
EDIT:
Clarification - Object Allocations in Instruments will always go up. It won't go down. It doesn't show deallocations, just allocations...
Related
I have developed application using ARC. In one of my UIViewController there are number of sub controllers (Like Buttons, Labels, Textfields, Textview, Scrollview) which all are having its IBOutlet. Here issue is that,I am using iOS 6.0.
With iOS 6.0 viewDidUnload method is deprecated. So at the time of Pop, this method is not called. I have checked with "product--> profile--> allocation" here whenever this controller is pushed in the navigation stack it increases the live memory Bytes but on pop Memory bytes don't decrease. Because of this after using an application for some time I am getting Received Memory Warning & application is going to be crashed in random instances.
Is there any alternative way to handle this kind of backend memory management issue.
First check in .h file that you property-sythesized with retain or not if with retain then set strong instead of retain like bellow..
#property ( nonatomic, strong) IBOutlet UITextField *yourTextField;;
I have found a few questions relating to this on SO and elsewhere, but none have a definitive answer. As far as I can tell, using ARC, my MKMapView is not being released (or at least is leaving garbage on the heap) when the view controller that contains it is released.
I don't think this is a silly problem on my end - I have spent a lot of time pouring over my code, testing small bits at a time, taking countless heapshots, ensuring that the mapView's delegate is being set to nil, etc, and in the end, this simple line:
self.mapView = [[MKMapView alloc] initWithFrame:CGRectMake(20, 3, 154, 171)];
is allocating memory that builds up by ~200 KB every time I go in and out of the view controller in which mapView is located.
So, my question is this: can anyone explain what is going on here? Is there a reason that ARC is not releasing memory taken up by my MKMapView? Is this a known issue? It looks an awful lot like a retain cycle to me, and quite a bit of memory is being lost, but it seems to me like this must be something going on behind the scenes...
EDIT
Here is the property declaration for my mapView:
#property (nonatomic, retain) MKMapView *mapView;
Keep in mind that the one and only thing I am doing with this MKMapView is alloc and init, as seen in the line from my original question (of course I'd like to do more with this map view, but I have narrowed it down to this line being the only part that is causing the leak - mapView is never even inserted into a view). When I comment that single line out, the leak disappears.
I've been trying to solve a problem to do with the image in my UIImageView being released due to memory warnings.
Here's my situation:
1) I declare a UIImageView in my .H:
IBOutlet UIImageView *fightStyleImage;
...
#property (nonatomic, retain) UIImageView *fightStyleImage;
2) I synthesize and dealloc in my .M:
#synthesize fightStyleImage;
...
...
-(void)dealloc{
[fightStyleImage release];
...
}
3) I attach the fightStyleImage to a UIImageView in Interface Builder.
4) Part of my app's experience allows a user to swipe on the device, to cycle through 5 different images. I am using the following code to achieve that:
// Load next image
UIImage *theImg = [UIImage imageNamed:#"fighter1.png"];
fightStyleImage.image = theImg;
Everything works really well, and I'm happy with the performance, experience, etc.
However, when I pop to another view controller (or to an MFMailComposeViewController, or an Address Book picker) and my device receives a memory warning (either through the simulator, or on the device), the following happens when I return to my original view controller: the iOS seems to jettison my UIImageView image (I assume because it is the most expensive object in memory), and I am left with a black screen (i.e. no image). If I begin to swipe again, the images return and continue to cycle properly.
I'd love to hear any thoughts on this, and thanks in advance for any solutions/insights anyone might have. In particular, I'm interested (of course!) in restoring my image that has been jettisoned from memory.
-SD
You need to properly implement the viewDidLoad and the viewDidUnload to setup and release your views. Read the iOS section of the Memory Management Programming Guide for assistance. I also recommend you move your IBOutlet declaration from the ivar to the property as so
UIImageView *fightStyleImage;
...
#property (nonatomic, retain) IBOutlet UIImageView *fightStyleImage;
The problem maybe due to using imageNamed: method as it caches the images into your memory and will be forced to free only when Low Memory warning occurs. Better go this way:
UIImage *image=[[[UIImage alloc]initWithContentsOfFile:imagePath]autorelease];
I keep running into situations with UIViewControllers containing a large amount of IBOutlets connecting the controller to its view's subviews (typically UILabels).
Following "best practices", i.e. use retain on all UI elements: #property (retain, nonatomic) UILabel *theElement1, #property (retain, nonatomic) UILabel *theElement2, ... gives me insane amounts of boiler plate code in dealloc and viewDidUnload for the view controller.
The offending IBOutlets are never used nor set outside the UIViewController (the set-method is only used in viewDidUnload and when the nib is loaded) except automatically when the nib is loaded.
The result from "best practice" is:
dealloc littered with [theElement1 release], [theElement2 release] etc.
viewDidUnload with [self setTheElement1:nil], [self setTheElement2:nil] etc.
However, since all of those elements are known to be retained by the view anyway, and the view is released by the UIViewController at appropriate times, I see absolutely no reason whatsoever for me to manually manage this.
The reason for this particular "best practice" (as far as I can tell) is to be consistent with your retains. But once you start having a large amount of outlets, you're more likely to miss handling the some outlet somewhere in either of the two methods, than you'll have trouble correctly changing outlets to "retain" for those special outlets you really want to retain even after the view is goodbye.
Is there some reason for this "best practice" other than the one I know about or should I feel quite free to break this "rule" in the particular case of subviews to an UIViewController's view?
You should stick to this best practice. It protects you from very bizarre crashes when you access IBOutlets after a memory warning. Yes, you need to manually manage your IBOutlets. Accessorizer does a nice job of automating this code.
Before ObjC 2.0, we had to write all of our accessors by hand, too (#property and #synthesize are very new additions to the language). Things have gotten a lot nicer. As we move to the 64-bit ABI and garbage collection, things get even simpler (and you should expect these things eventually to make their way to iPhone).
But for now, follow the memory management rules as laid out in Memory Management of Nib Objects. You trade a really small amount of typing for a huge amount of debugging. (Hmm, looks like they've updated this doc again; time to study up myself.)
Can somebody can please verify that they can also reproduce that memory leak.
Create a new "Utility Application". Open the FlipsideView.xib and add a UITextview. Using the inspector, uncheck "Editable" and check "Detects Phone Number" and "Detects Links".
Run the app using the Leak instrument on an iPhone. Flip between the MainView and the FlipsideView a few times and observe the leak.
Thanks
I'm using 3.1.2
Your leak seems to be somewhere else, i tried what you say and no leaks show up when im using 3.1.2 .
However, i must add i did not connect the uitextview with IBOutlet as you did not mention it. If you are using
#property(nonatomic,retain) IBOutlet UITextView *....
it may cause a leak if you do not release your IBOutlet in dealloc.
Make sure you run Leaks against a real device, and not the simulator. I've found in the past that leaks were reported running my app against the simulator, but when I ran against a real device, those reported leaks went away.