iPhone Development

Just another iPhone Blog

Efficient Memory Handling in UIViewController-Part 1

“Low Memory Warning” “Low Memory Crash” are the one’s that frightens iPhone Developers.

There are many posts in various blogs explaining how to efficiently utilize the available memory, and some have tips in memory management. Most of the Cases, as I have seen, these memory issues arises often due to some negligence/improper handling of resources, esp. images, views, cached data and so on.

As the saying goes “Prevention is better than cure”, This post FOCUS on

  • Handle memory warnings
  • Safe release of all the views
  • Releasing Data models
  • Releasing Caches
  •  

    in a ViewController, which we use it very often, and to some extent is the root cause of Memory issues we encounter.

    Here is a typical template of UIViewController:

    @interface myViewController(Private)

    -(void)releaseAllViews;

    -(void)customInitialisation; @end

     

     

    @implementation myViewController(Private)

    -(void)releaseAllViews;

    {

    // release all views this controller own

    }

     

    -(void)customInitialisation {

    // do the initialization of class variables here..

    should act as constructor for this class

    }

    @end

    STEP 1: A method, name it as releaseAllViews , which is responsible to release all & ONLY the Views, referenced either by IBOutlets, or view elements created in viewDidLoad method or elsewhere in the class.


    @implementation myViewController

    -(id)initWithNibName:(NSString*)nibName bundle:(NSBundle*)nibBundle

    {

    //call super method

    self =[super initWithNibName:nibName bundle:nibBundle];

    if(self)

    {

    [self customInitialisation];

    }

    return self;

    }

    //Invoked when the class is instantiated in XIB

    -(id)initWithCoder:(NSCoder*)aDecoder

    {

    self = [super initWithCoder:aDecoder];

    if( self)

    {

    [self customInitialisation];

    }

    return self;

    }

    STEP 2: I would have a method which initializes all my class variables, also acts as a constructor, and this is typically invoked by “initWithNibName” (creating view controller programmatically) and “initWithCoder” (in case view controller is created in XIB).


    -(void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning]

    //Release all your caches like say Image Cache, any File Data etc.

    }

    STEP 3: didReceiveMemoryWarning is invoked at various times at different Memory Levels of the application. Make sure you release all the heavy objects like Images, Data and so on and don’t forget to make sure that these cached data should be able to restore their state in future, without having any impact on the application.


    -(void)viewDidUnload {

    [super viewDidUnload];

    //release all your views, which the controller owns, here

    [self releaseAllViews];

    }

    STEP 4: viewDidUnload is invoked when the system identifies that your view is no longer visible on screen, when the memory warning notification arrives. Make sure you call releaseAllViews to relinquish the ownership of the views the controller owns.

     

    -(void)dealloc {

    //remove as Observer from NotificationCenter, if this class has registered for any notifications

    [[NSNotificationCentre defaultCenter] removeObserver:self];

    [self releaseAllViews];

    //release all you member variables and appropriate caches

    }

    STEP 5: Release all your views, data cache, member variables, and remove as observer, incase the controller is registered to any of the notifications.


    In Part-2 of this Post, I will provide Xcode Templates for UIViewController class which includes all the above steps.

    Here I Leave this links which provides you tips in Memory Management in iPhone OS

  • iPhone Memory Management
  • 10 iPhone Memory Management Tips
  • UPDATE:

    One way to test the Memory Warning scenarios, one would use the Hardware -> Simulate Memory Warning menu in iOS Simulator. But, For some lazy people like me or for those smart people who wants the application to be periodically check for the memory warning at the background, I found a Code snippet from iDevRecipes

    All you need to do is to place the below code in your App Delegate

    #if TARGET_IPHONE_SIMULATOR

    - (void)simulateMemoryWarning

    {

    CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), (CFStringRef)@”UISimulatedMemoryWarningNotification”, NULL, NULL, true);

    }

    #endif

     

    Place the below code in your application:didFinishLaunchingWithOptions: method (preferably in the first line of this method)

    #if TARGET_IPHONE_SIMULATOR

    //lets call the simulate warning every 5 minutes (300 seconds)

    [NSTimer scheduledTimerWithTimeInterval:300.0 target:self selector:@selector(simulateMemoryWarning) userInfo:nil repeats:YES];

    #endif

    NOTE: The above code snippets has to be placed between TARGET_IPHONE_SIMULATIOR  and #endif to make sure that this code is only executed in the Simulator, as we are using thing which are undocumented and if used in App Store builds, it would violate Apple SDK policy and application could be rejected.

     

     

     

     

    About these ads

    7 responses to “Efficient Memory Handling in UIViewController-Part 1

    1. Thomas June 13, 2010 at 12:24 pm

      Nice template dude, I’m just wondering how to actually remove the uiviewcontroller object. I have a function that visualizes a uiviewcontroller based on a dynamic data set. I constantly want to remove the uiviewcontroller instance from the superview + from the memory entirely ( it has custom objects inside that listen to notifications etc…

      if (self.myView2.view.superview == nil){
      if (self.myView2 == nil)
      {
      //mycode
      }
      }

      How do I get self.myView1 to be nil on a correct way?

      Doing:

      [self.myView1.view removeFromSuperview];
      self.myView1 = nil;

      result in several: “modifying layer that is being finalized” errors.

      Any idea?

      ps: I read this post about the specific error:
      http://blog.evandavey.com/2009/03/how-to-solve-modifying-layer-that-is-being-finalized-iphone-sdk.html

      Greets,

      Thomas | A fellow iphone addict

    2. bharath2020 June 13, 2010 at 12:58 pm

      The answer is with you!
      How did you chose to present the UIViewController u r referring in your context?

      Is it either pushViewController (if so, do popViewController…)
      OR
      presentModalViewController (do dismissModalViewCotntroller…)

      Dont get smart to remove self.view yourself, Leave the job to UIViewController..

      Hope it answers your query.

    3. Thomas June 13, 2010 at 1:22 pm

      I actually just used this line of code:

      DrinksView *myDrinksView = [[DrinksView alloc]initWithNibNameAndDataSet:@”DrinksView” dataSet:[self.pagesArray objectAtIndex:currentPage]RemovedObjectFromDataSet:NO];

      [myDrinksView.view setFrame:CGRectMake(0.0, 44.0, 320, 367.0)];
      self.myView1 = myDrinksView;
      [myDrinksView release];
      [self.view insertSubview:myView1.view atIndex:0];

      Based on a source example from ‘Beginning iPhone Development’ by Apress ( 06 – View Switcher )

      • bharath2020 June 13, 2010 at 4:09 pm

        I hopefully would be wrong if you are using this way to bring up a view controller unless you do have a specific purpose in it.

        However, to answer your question,
        * Your DrinksView would be release once the viewcontroller/ object of the class which contains this code is released

        * Also make sure you have this code snippet inside viewDidLoad method, so that it would work as expected in case view is unloaded due to Memory Warnings

        Hope this helps

    4. Alper Tayfun December 18, 2010 at 12:35 pm

      Hello,

      I’m coding on Objective-C. I know objective-c college level. However , I’m building for IPad App. But i have an more memory problems.
      I was read your article but i don’t solve my errors.
      Anyway,

      If you want to check my code then i will sent an email ?

      Best regards,
      AT

    5. Pingback: Why iOS Apps Crash? | DevMaster.vn

    6. Pingback: [iOS] Why iOS Apps Crash | SETA Geeks

    Leave a Reply

    Fill in your details below or click an icon to log in:

    WordPress.com Logo

    You are commenting using your WordPress.com account. Log Out / Change )

    Twitter picture

    You are commenting using your Twitter account. Log Out / Change )

    Facebook photo

    You are commenting using your Facebook account. Log Out / Change )

    Google+ photo

    You are commenting using your Google+ account. Log Out / Change )

    Connecting to %s

    Follow

    Get every new post delivered to your Inbox.

    Join 28 other followers

    %d bloggers like this: