[Ios]received Memory Warning

Source: Internet
Author: User

Reference: http://blog.sina.com.cn/s/blog_68661bd80101nn6p.html

The memory available to each app under the iphone is limited, and if an app uses more than 20M of memory, the system sends a warning message to the app. Apple's system engineers suggest that the application should not take up more than 20MB of memory, and a rough rule of thumb is circulating in the developer Circle: the iphone starts issuing a memory warning when the application consumes about 20MB of memory. iphone OS shuts down the application when the application occupies approximately 30MB of memory. After you receive this message, the app must handle it correctly, or there may be an error or a memory leak. When the app receives memory warning, it calls: UIApplication::d idreceivememorywarning-uiapplicationdelegate:: Applicationdidreceivememorywarning, and then invokes all current viewcontroller for processing. So the main work to be done is in Viewcontroller.

We know that when you create Viewcontroller, the order of execution is Loadview, viewdidload.

When a memory warning is received, if Viewcontroller is not displayed (in the background), didreceivememorywarning, Viewdidunload is executed, if Viewcontroller is currently being displayed (in the foreground), Only the didreceivememorywarning is executed.

When the Viewcontroller is re-displayed, the Viewcontroller that performed viewdidunload (that is, the original in the background) will recall Loadview-viewdidload.

When overloading didreceivememorywarning, be sure to call the super implementation of this function to allow the parent class (typically Uiviewcontroller) to release Self.view. After the Self.view is released, the following Viewdidunload function is called. In other words, although self.view is handled, the outlets variable is not released because it has been retain, so in order to solve this problem, we need to release these r in Viewdidunload. Etain the outlets variable. Usually the controller saves a reference to the views created by the nib file, but it may also hold a reference to the object that the Loadview function creates. The perfect method is to use the Synthesizer method:

Self.mycertainview = nil;
The synth will release the view, and if you don't use the property, you have to explicitly release the view yourself.

Therefore, the following functions are mainly noted:

Loadview Create view, build interface;
Viewdidload Do some initialization work. Because it is called when the Viewcontroller is first created and re-restored, this function needs to be careful to distinguish between different situations and set the correct state.
Didreceivememorywarning Frees unnecessary memory, such as cache, view not displayed, etc.
Viewdidunload The maximum amount of free memory that can be freed. For example, you should release the view, which can be regenerated after calling Loadview. (where member variables should be set to nil after they are freed). For non-interface data is released, the need for specific analysis, can be recovered data can be released, unrecoverable data will not be released.

In fact, if Viewcontroller is generated by Xib interface, we need to do less, mainly in the Viewdidload to restore the original interface state.

If you are creating a programming interface, you need to do more work, and all 4 of the above functions need to be handled correctly.

iOS6.0 and later, Viewdidunload no longer useful, received low-memeory when the system will not release views.
Memory warning for iOS6.0 and later:
Calling Super's didreceivememorywarning call within didreceivememorywarning only releases the controller's Resouse and does not release the view
Processing method:
-(void) didreceivememorywarning
{
[Super didreceivememorywarning];//does not automatically release Self.view even if it is not displayed on the window.
ADD code to your own resources is no longer necessary.
Here to do compatible processing need to add ios6.0 macro switch, guaranteed to be used under 6.0, 6.0 blocked the following code before, otherwise it will be automatically loaded when using Self.view below Viewdidload
if ([self.view window] = = nil)//is the view being used

{
ADD code to preserve data stored in the "that" might be
Needed later.
ADD code to strong references to the view in
The view hierarchy.
Self.view = nil;//The purpose is to re-load the call viewdidload function when it is again entered.
}

}
But it seems that the writing is not easy compared to the previous. In the end, we found an article in which the article said it was not worth reclaiming this part of the memory for the following reasons:
1. UIView is a subclass of Uiresponder, and Uiresponder has a calayer member variable, Calayer is specifically used to draw yourself onto the screen.
2. Calayer is a wrapper class for bitmap images, and Calayer creates this bitmap image class when UIView calls its own drawrect.
3. The actual memory is actually a bitmap image class, Calayer only accounted for 48bytes, UIView only accounted for 96bytes. and an ipad full-screen UIView of the bitmap class will take up to 12M size!
4. When iOS6, the system automatically recycles the bitmap class when the system issues memorywarning. However, the UIView and Calayer classes are not recycled. This means that most of the memory is reclaimed, and can be rebuilt according to the Calayer class when the bitmap class is required.
So, what iOS6 to do is that we don't need to recycle memory for dozens of byte at all.
The memory of the mobile device terminal is very limited, the application must do the low-memory processing, in order to avoid the program because the memory usage is too big and crashes.

Low-memory Treatment Ideas
Typically an application contains multiple view controllers, and when you jump from view to another view, the previous view is just not visible and will not be cleaned up immediately, but saved in memory for the next quick appearance. However, if the application receives the Low-memory warning from the system, we have to clear out the views of the current invisible state, freeing up more memory for use, and the currently visible view controller should release some cached data reasonably. Picture resources and some resources that are not in use to avoid application crashes.

The idea is that specific implementations vary slightly depending on the system version, and this article will explain in detail the low-memory processing of iOS 5 and iOS 6.

Handling of IOS 5
Prior to iOS 6, if the application received a low-memory warning, the currently invisible view controllers would receive a viewdidunload message (also understood to call the Viewdidunload method automatically), so we need to The Viewdidunload method frees all outlets and resources that can be created again. The currently visible view controller uses didreceivememorywarning to rationally release resources, as described in code comments.

To give a simple example, there is a view controller:
@interface Myviewcontroller:uiviewcontroller {
Nsarray *dataarray;
}
@property (nonatomic, strong) Iboutlet UITableView *tableview;
@end

The corresponding processing is:
#pragma mark-
#pragma Mark Memory Management

-(void) didreceivememorywarning {
Releases the view if it doesn ' t has a superview.
[Super didreceivememorywarning];
Relinquish ownership any cached data, images, etc-aren ' t in use.
}

-(void) Viewdidunload {
Relinquish ownership of anything that can is recreated in viewdidload or on demand.
for example:self.myOutlet = nil;
Self.tableview = nil;
DataArray = nil;

[Super Viewdidunload];
}

Handling of IOS 6
IOS 6 Deprecated The Viewdidunload method, which means that everything needs to be done by ourselves in didreceivememorywarning.
What should be done specifically?

1. Place the outlets as weak
When view Dealloc, no one holds a strong reference to Subviews, then the subviews instance variable is automatically empty.
@property (nonatomic, weak) Iboutlet UITableView *tableview;

2. Empty the cache data in didreceivememorywarning
#pragma mark-
#pragma Mark Memory Management
-(void) didreceivememorywarning
{
[Super didreceivememorywarning];
Dispose of any resources the can be recreated.
DataArray = nil;
}
Do not forget a little, whenever tableview reload, need to judge DataArray, if empty is re-created.

Compatible with iOS 5 and iOS 6
Well, the point is, what if you want the program to be compatible with iOS 5 and iOS 6? Here's a little tip, we need to do something about didreceivememorywarning:
#pragma mark-
#pragma Mark Memory Management

-(void) didreceivememorywarning
{
[Super didreceivememorywarning];

if ([self isviewloaded] && Self.view.window = = nil) {
Self.view = nil;
}

DataArray = nil;
}

Determine if the view is part of a window, and if not, you can rest assured that Self.view is empty in exchange for more available memory.

What would be the phenomenon? If, from view controller a jumps to view controller B and then simulates the low-memory warning, view controller A will execute Self.view = nil; When we return a from B, a will recall the viewdidload once, when the data is all re-created, simple and compatible with no pressure ~ ~

Note:
If you're curious about why Apple abandoned viewdidunload, you can look at Apple's explanation:
Apple deprecated viewdidunload for a good reason. The memory savings from setting a few outlets to nil just weren ' t worth it and added a lot of complexity for little benefi T. For IOS 6+ apps, you can simply forget about view unloading and only implement didreceivememorywarning if the view cont Roller can let go of cached data so can recreate on demand later.


Original address: http://justsee.iteye.com/blog/1820588
Official document: https://developer.apple.com/library/ios/#featuredarticles/viewcontrollerpgforiphoneos/ Viewloadingandunloading/viewloadingandunloading.html

Viewcontroller life cycle and post-didreceivememorywarning process: http://blog.csdn.net/iunion/article/details/8699491


The execution process for each method in the Viewcontroller life cycle is as follows: init->loadview->viewdidload->viewwillapper->viewdidapper-> Viewwilldisapper->viewdiddisapper->viewwillunload->viewdidunload->dealloc
Follow the following text to understand the Viewcontroller view loading process:

1 First determine if the subclass overrides Loadview, if there is a direct call. After that, the viewdidload completes the view loading.

2 If you specify the nib file name externally by calling Initwithnibname:bundle, Viewcontroller record this nib to create the view.

3 if the name parameter of Initwithnibname:bundle is nil, Viewcontroller will find the nib associated with it in the following two steps.

A if the class name contains a controller, for example, the class name of Viewcontroller is Myviewcontroller, the lookup exists for myview.nib;

B find the same file as the Viewcontroller class name, such as Myviewcontroller, to find out if there is a myviewcontroller.nib.

4 If the subclass does not have an overridden Loadview, Viewcontroller will find or call its default loadview from Stroyboards, and the default Loadview returns a blank UIView object.

Note that the first step, Viewcontroller, is to determine whether the subclass overrides the Loadview, rather than judging whether the Viewcontroller view is empty after the loadview of the child class is called. That is, if the subclass overrides the Loadview, whether the subclass can get to the View,viewcontroller in Loadview will directly viewdidload complete the load of the view

Then why write Self.myoutlet = nil; , this syntax is actually executed in the property of the setter method, rather than a simple variable assignment, it did two things: 1, old data release off, 2, new data (nil) retain (when the property is set to retain), of course Nil retain is meaningless. If written as Myoutlet = nil, it is simple to point myoutlet to nil, so that the memory leaks, because the old data is not released. And if you just write [Myoutlet release] There will be problems, because when the view is Dealloc will again release, the program is wrong, and nil release is no problem.

Dealloc is the current Viewcontroller is released, emptying all the current viewcontroller inside the entity and data to free memory, the method is also automatically called, do not need to be executed manually. For example, this method is automatically called when Modalview is dismissmodalviewcontrolleranimated or navigationcontroller back to the previous page. Since this page is no longer in use, it is possible to release (release) all the entities and data.

[Ios]received Memory Warning

Related Article

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.