I used Instrument to test my app with 2 ViewControllers that go forth and back with button via segue. I noticed that all of my UILabel in ViewController1(created using Interface Builder) keep adding up my memory allocation every time I go to ViewController1. Is there somewhere in the setting that I can set so that it will deallocate or at least not growing?
Try setting all your UILabels to nil on the dealloc method.
- (void)dealloc
{
self.mYLabel = nil;
[super dealloc];
}
Related
What am I doing is I am creating lots of UIView in the background and keep them in a NSMutableArray to use later. But when I dismiss the view controller I check the memory in Xcode and it seems some of memory not being released. I checked; view controller is being deallocated.
Check please:
This happend after several showing and dismissing the view controller. Some of them is being released but not all.
Thanks.
Uncheck Enable Zombie Objects option under Edit Scheme. And try again.
A zombie is an object that has been deallocated, but references to it still exist and messages are still being sent to it
I think this link has more info for you
What is NSZombie?
I suppose you use arc, so it might be useful to explicitly release this in dealloc.
-(void)dealloc {
for(UIView *vw in self.arrayOfViews) {
vw = nil;
}
self.arrayOfViews = nil;
}
Using dealloc is a bit like the old days (pre-arc), but it will help you manage memory better.
!important! --> NEVER call [super dealloc]; when using arc!
In dealloc method release all views that you have in the array.
called the below method in your controller dealloc method
- (void)releaseViewArray
{
// Releasing views in the array
for (UIView *view in _viewArray) {
[view release];
}
// Releasing the array that holding the views
[_viewArray release];
}
In iOS, I pop from current viewController into previous one, but it doesn't go into dealloc.
Is this because there is another pointer pointing towards the current viewController, either in a different viewController or in the current one?
This is where I pop to previous view:
- (IBAction)fileUploadCancelTouched:(UIButton *)sender {
[self.fileToUpload cancel];
[self.view hideToastActivity];
[self.greenprogressBar removeFromSuperview];
[self.subView removeFromSuperview];
self.fileUploadCancelButton.hidden = YES;
if (self.commandComeBackToFinalScreen == 1) {
[self.navigationController popViewControllerAnimated:YES];
}
}
This is my dealloc function:
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
self.greenprogressBar = nil;
self.fileUploadCancelButton = nil;
self.fileToUpload = nil;
[buttonHome_ release];
[buttonTestMeAgain_ release];
[buttonMarkMyTest_ release];
[examId_ release];
[sender_ release];
self.ob = nil;
[_fileUploadCancelButton release];
[super dealloc];
}
Check to make sure that ARC is not enabled in your project. If it is not ARC enabled then dealloc should be called unless your code is retaining your view controller. You should check through the Instruments tool if your pop commands reduces memory or not.
There may be some other reasons as mentioned in another answer that I am posting below:
The obvious reason is that something is retaining your viewController. You will have to look closely at your code. Do you do anything that in your class that uses delegates, since they sometimes retain the delegate. NSURLConnection will retain your class, and so does NSTimer. You can scatter code in you class and log your class's retain count, and try to find out where. In the code you showed so far the retain could should just be 1, since the class is only retained by the navigation controller.
Also, before you pop your view, get a reference to it, pop it with NO animation, and then send it some message that has it report the retain count (this would be some new method you write). That new method could also log other things, like whether it has any timers going, NSURLConnections, etc.
First of all, get rid of [super dealloc]. I know that's intuitive, but the documentation says don't do it.
In my own case, I had an observer & timer in my dealloc method, but that wouldn't run since the timer had a strong pointer to the controller.
Created a dedicated clean up method which removed the observer & invalidated the timer. Once that ran, the controller was correctly deallocated.
Hello I have a memory issue in my iPad app. Each time I change from a view to another view (this transition is made with segues), the app is increasing the memory used and never releases the memory. It is always increasing the memory used.
Let's see an example:
I am in my first view "home" which has these lines in viewDidLoad and viewDidAppear
(void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"background.png"]];
[self initializeHomeDataSources];
DateService* dateService = [[DateService alloc] init];
self.currentDate = [dateService today];
[self checkHomeStatus];
[self showEmptyHomeViews];
[self setUpFonts];
}
and this my view did appear method
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
_homeAutomaticUpdate = YES;
//This is a Thread
[NSThread detachNewThreadSelector:#selector(automaticHome) toTarget:self withObject:nil];
[self.phrasesView startPhrasesThread];
if ([InternetService internetConnection]) {
[self synchronizeHome];
}
if (self.scheduleDataSource.currentEvent) {
[self loadMessagesFor:self.homeDataSource.currentEvent];
[self loadLibraryFor:self.homeDataSource.currentEvent];
} else {
[self loadLibrary];
}
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
_homeAutomaticUpdate = NO;
}
All the IBOutlet's are defined as (nonatomic, strong).
Each time the HomeView is loaded the memory increases it's quantity and I don't know what is happening.
Can anybody help me here? This problem is causing me consternation.
I'm guessing that you're going "backwards" to previous controllers using segues. Is that true? If so, that's your problem -- unless you use an unwind segue, you should never go backwards using segues because they always instantiate new controllers. So, when going back to previous controllers, either use an unwind, or use code that reverses your forward segues -- that is, popViewControllerAnimated: if the forward segue was a push, and dismissViewControllerAnimated:completion: if the segue was a modal.
Few questions:
Is your app killed after a while, because of memory usage?
Why you are creating new thread in -viewDidAppear?
Have you tried to simulate memory warning?
(In simulator: Hardware -> Simulate Memory Warning or Shift + CMD + M)
Does the memory gets down after memory warning or not?
This is not a whole answer for your question but your outlets must be weak unless their not top level objects.
All the IBOutlet's used should be (nonatomic, weak). Try this out..
I'm displaying a modal view called "rule" from a round rect button. In that "rule" modal view i'm displaying another modal view called "newRule" when user clicks the Create Rule button.
When i'm quitting from the "newRule" modal view the app crashes. Here's the code i had written for quitting the "newRule" modal view.
[self dismissModalViewControllerAnimated:YES];
Nothing is displayed in the console. When i tried to debug the code, it displayed a EXC_BAD_ACCESS after the dealloc method. My dealloc method looks like this:
[label release];
label = nil;
[imageArray release];
imageArray = nil;
[languageElementsArray release];
languageElementsArray = nil;
[super dealloc];
Please help me.
Is the label a UILabel object? Also what are in the arrays? Views are automatically released once their superview is released, so releasing a subview after its superview has been released (or releasing the subview then the superview) will cause an crash similar to the one you describe
I'm experiencing something similar. When I comment out the last line ( [super dealloc] ), it then works. Does this make a difference for you?
If you happen to be using Automatic Reference Counting in Xcode 4.2, then you should not have a [super dealloc] at all—which would result in this error.
Of course, in that context you likely should not be releasing these other objects either.
I'm making a split-view based iPad application(Portrait mode only), and I want to know how to recover initial state after viewDidUnload is called.
When split-view application started for the first time,
-splitViewController:willHideViewController:withBarButtonItem:forPopoverController:
is called automatically (right after -viewDidLoad).
I prepares UIBarButtonItems in the method.
If I open modal dialog or something with UIWebViewController (it consumes a lot of memory), application receives memory warning, viewDidUnload(s) are called.
When I close the modal dialog, -viewDidLoad is called automatically, but this time
-splitViewController:willHideViewController:withBarButtonItem:forPopoverController: is not called.
I prepares UIBarButtonItems in
-splitViewController:willHideViewController:withBarButtonItem:forPopoverController:
but it is not called, so buttons are dismissed.
In that case, should I call the method manually?
I found similar posting here.
https://github.com/grgcombs/IntelligentSplitViewController/issues/6
Thanks.
I don't know it is OK to answer to my own question, but maybe I found an answer for this. http://osdir.com/ml/cocoa-dev/2011-02/msg00430.html
It says that we should preserve BarButtonItems in viewDidUnload, and load it in viewDidLoad.
It seems working fine.
- (void)viewDidUnload {
[super viewDidUnload];
self.toolbarItems = self.toolbar.items; // property with retain policy
}
- (void)viewDidLoad {
[super viewDidLoad];
if (self.toolbarItems) {
self.toolbar.items = self.toolbarItems;
self.toolbarItems = nil;
}
}