前言
iPhone手機用戶大多有一個習慣:用完的應用直接Home鍵。因為大家都知道系統本身會幫我們管理這些應用的存活,這樣就給我們iOS 開發帶來了挑戰!當運行內存吃緊的時候,要及時處理防止應用被殺。
手機運行內存越來越大2G,4G,8G……但是應用也越來越復雜了,所以我們很需要做一些預防措施。
iPhone內存機制是這樣的:當應用推到后臺是,系統維護一個隊列,隊列里的應用按優先級區分,等內存警告的時候就按照優先級去kill。所以我們要做的就是收到內存警告的時候去清理應用的緩存釋放物理內存,能有效預防被kill。如果收到內存警告不去處理3次可能就被kill了!!!
除了平時養成良好的代碼習慣,還要注意一下內容:
1、處理內存警告
- 在什么地方處理
[UIApplationDelegate applicationDidReceiveMeoryWaring]
[UIViewcontroller didReceiveMemoryWaring]
UIApplicationDidReceiveMemoryWoringNotification
- 需要處理什么
清除圖片等占用內存多的資源
單例對象不要創建之后一直持有對象數據 警告時釋放
隱藏的viewcontroller直接設置self.view=nil
- 示例代碼如下:
-(void)didreceivermemoryworing{
[super didreceivememorywaring];
_testdata= nil;
}
2、降低內存峰值
lazyalloction path_one直到使用時才分配 線程安全 不僅分配對象 還有資源文件
Calloc 替代malloc 設置清0標記 只有讀寫操作的時候才會映射到物理內存并初始化
稍微大一點的圖片把imagenamed換成imagewithcontentoffile不緩存
Releasepool 檢測主線程分配過大內存或者快速分
imageNamed: 這個方法用一個指定的名字在系統緩存中查找并返回一個圖片對象如果它存在的話。如果緩存中沒有找到相應的圖片,這個方法從指定的文檔中加載然后緩存并返回這個對象。因此imageNamed的優點是當加載時會緩存圖片。所以當圖片會頻繁的使用時,那么用imageNamed的方法會比較好。
例如:你需要在 一個TableView里的TableViewCell里都加載同樣一個圖標,那么用imageNamed加載圖像效率很高。系統會把那個圖標Cache到內存,在TableViewCell里每次利用那個圖 像的時候,只會把圖片指針指向同一塊內存。正是因此使用imageNamed會緩存圖片,即將圖片的數據放在內存中,iOS的內存非常珍貴并且在內存消耗過大時,會強制釋放內存,即會遇到memory warnings。
而在iOS系統里面釋放圖像的內存是一件比較麻煩的事情,有可能會造成內存泄漏。
例如:當一 個UIView對象的animationImages是一個裝有UIImage對象動態數組NSMutableArray,并進行逐幀動畫。當使用imageNamed的方式加載圖像到一個動態數組NSMutableArray,這將會很有可能造成內存泄露。原因很顯然的。
imageWithContentsOfFile:僅加載圖片,圖像數據不會緩存。因此對于較大的圖片以及使用情況較少時,那就可以用該方法,降低內存消耗。
下面列舉出兩種方法的詳細用法:
NSString*path = [[NSBundlemainBundle] pathForResource:@”icon” ofType:@”png”];
UIImage*image = [UIImageimageWithContentsOfFile:path];
以及:
NSString*filePath = [[NSBundlemainBundle] pathForResource:fileName ofType:“png”];
NSData*image = [NSDatadataWithContentsOfFile:filePath];
UIImage*image = [UIImageimageWithData:image];//or = [UIImage imageWithContentsOfFile:filePath];
4、大文件優化內存映射方式
[nsdata datawithcontentsoffile:path]
換成
[nsdata datawithcontentsoffile:path options:nadatareadingmappedifsafe error:&error]
同樣是內存映射的方式 是有用的時候才會映射到物理內存 大文件使用
5、設置緩存機制
a、`nacache`設置`totalcostlimit&countlimit `監聽內存警告并刪除所有的`cache`
b、`Nspurgabledata`適用于大數據低內存的時候自動移除
6、觀察log文件
找到lowmemory.log
7、單例模塊化
控制單例等全局變量
8、建立清理預防機制
iOS4.0以后系統支持多任務類型,程序按下home鍵后,程序進入后臺運行,如果內存不足被系統關閉或者手動關閉,都不會調用applicationWillTerminate回調函數。
解決方法:可以在程序進入后臺時,添加一后臺運行通知函數,也就是程序進入后臺一段時間內,程序還在運行,并可以響應一些消息。
代碼如下:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
[[UIApplication sharedApplication]beginBackgroundTaskWithExpirationHandler:^(){
//程序在10分鐘內未被系統關閉或者強制關閉,則程序會調用此代碼塊,可以在這里做一些保存或者清理工作
NSLog(@"程序關閉");
}];
}
添加此段代碼后,程序進入后臺10分鐘內會響應 applicationWillTerminate函數,可以在其中添加保存或者清理工作。
這樣不僅優化了項目內存電量使用還能有效的后臺保活了,趕快做起來吧!
手機瀏覽
全國
19974831731





