How to implement didReceiveMemoryWarning?

前端 未结 6 1850
一生所求
一生所求 2020-11-30 19:38

I have developed a simple location aware iPhone application which is functionally working very well to our expectations except in the low memory condition of the phone .

相关标签:
6条回答
  • 2020-11-30 20:07

    You could also release memory in didReceiveMemoryWarning, that you allocated for static variables in your classes. Because once the memory for static variables is allocated it'll not be freed during the application runs.

    0 讨论(0)
  • 2020-11-30 20:08

    Memory warnings are a signal to you that you should dispose of any resources which aren't absolutely critical. Most of your controllers will be hanging onto data caches, intermediary data, or other bits and pieces, often to save recalculation. When they receive memory warnings, they should begin flushing anything they don't immediately need in order to operate.

    How you determine what is "critical" depends entirely on your application's design. An OpenGL game, for example, may determine that textures currently on-screen are valuable and flush textures which aren't visible, or level data which is outside the bounds of the current play area. An application with extensive session logs (like an IRC client) may flush them out of memory and onto disk.

    As you observed, the warning is sent to each controller in your hierarchy, so each piece needs to determine individually what data constitutes "critical for operation" and what constitutes "expendable". If you've optimized them all and are still getting out of memory warnings, it's unfortunately time to revisit your core application design, because you're exceeding the limits of the hardware.

    0 讨论(0)
  • 2020-11-30 20:10

    One example i am posting...which i have copied from somwhere... it might give you some idea...

    - (void)didReceiveMemoryWarning {
    
        // Release anything that's not essential, such as cached data (meaning
        // instance variables, and what else...?)
    
        // Obviously can't access local variables such as defined in method
        // loadView, so can't release them here We can set some instance variables
        // as nil, rather than call the release method on them, if we have defined
        // setters that retain nil and release their old values (such as through use
        // of @synthesize). This can be a better approach than using the release
        // method, because this prevents a variable from pointing to random remnant
        // data.  Note in contrast, that setting a variable directly (using "=" and
        // not using the setter), would result in a memory leak.
        self.myStringB = nil;
        self.myStringD = nil;
        [myStringA release];// No setter defined - must release it this way
        [myStringC release];// No setter defined - must release it this way
    
        /* 3. MUST CONFIRM: NOT necessary to release outlets here - See override of
           setView instead.
        self.labelA = nil;
        self.imageViewA = nil;
        self.subViewA = nil;
         */
        // Releases the view if it doesn't have a superview
        [super didReceiveMemoryWarning];
    }
    
    0 讨论(0)
  • 2020-11-30 20:16

    It's up to you to decide what to do in didReceiveMemoryWarning. The OS is telling you that memory is low, and you need to free up as much as you can as soon as you can. The idea is that you should free any cached data, unload views that aren't visible, etc. The details are application specific.

    0 讨论(0)
  • 2020-11-30 20:20

    On iOS 5 and earlier.

    When controller receive a memory warning, didReceiveMemoryWarning will be called. At that time, if controller's view is not in the view hierarchy, the view will be set to nil and viewDidUnload will automaticly invoked. So the things we must do in viewDidUnload is releasing sub view created in viewDidLoad or created from Nib. Like this:

    - (void)viewDidUnload
    {
        self.subView = nil;
        self.subViewFromNib = nil;
    }
    
    - (void)didReceiveMemoryWarning
    {
        self.someDataCanBeRecreatedEasily = nil;
        [super didReceiveMemoryWarning];
    }
    

    On iOS6.

    The controller doesn't automaticly release the view when receive a memory warning. So the viewDidUnload never be called. But we still need to release our view (including sub view) when a memry warning happens. Like this.

    - (void)didReceiveMemoryWarning
    {
        if ([self isViewLoaded] && [self.view window] == nil) {
            self.view = nil;
            self.subView = nil;
            self.subViewFromNib = nil;
        }
        self.someDataCanBeRecreatedEasily = nil;
        [super didReceiveMemoryWarning];
    }
    

    Note that we don't call [self view] before we know the view is loaded. cause the this method will automaticly load view if the view is not loaded.

    Note that we can release the view just when the view is not added to a window.

    0 讨论(0)
  • 2020-11-30 20:24

    To my surprise, only a few apps in the official iPhone samples implement didReciveMemoryWarning. You can use the iPhoneCoreDataRecipes example as an reference.

    Some samples (e.g. TableViewSuite) even do something else ;-)

    0 讨论(0)
提交回复
热议问题