內存方面常見問題:
1瞧壮、UIGraphicsEndImageContext
UIGraphicsBeginImageContext和UIGraphicsEndImageContext必須成雙出現搬设,不然會造成context泄漏。另外XCode的Analyze也能掃出這類問題膘婶。
2恒水、UIWebView
無論是打開網頁倔幼,還是執(zhí)行一段簡單的js代碼,UIWebView都會占用APP大量內存修壕。而WKWebView不僅有出色的渲染性能愈捅,而且它有自己獨立進程,一些網頁相關的內存消耗移到自身進程里慈鸠,最適合取替UIWebView蓝谨。不過目前蘋果已經強制iOS開發(fā)者使用WKWebView
3、autoreleasepool
通常autoreleased對象是在runloop結束時才釋放青团。如果在循環(huán)里產生大量autoreleased對象譬巫,內存峰值會猛漲,甚至出現OOM壶冒。適當的添加autoreleasepool能及時釋放內存缕题,降低峰值截歉。
4胖腾、互相引用
比較容易出現互相引用的地方是block里使用了self,而self又持有這個block瘪松,只能通過代碼規(guī)范來避免咸作。另外NSTimer的target、CAAnimation的delegate宵睦,是對Obj強引用记罚。使用的時候要注意。
5壳嚎、大圖片處理
舉個例子一般圖片縮放接口是這樣寫的:
- (UIImage)scaleImage:(UIImage)image newSize:(CGSize)newSize {
UIGraphicsBeginImageContextWithOptions(newSize, NO, 0);
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
但處理大分辨率圖片時桐智,往往容易出現,原因是-[UIImage drawInRect:]在繪制時烟馅,先解碼圖片说庭,再生成原始分辨率大小的bitmap,這是很耗內存的郑趁。解決方法是使用更低層的ImageIO接口刊驴,避免中間bitmap產生: - (UIImage)scaleImageWithData:(NSData)data withSize:(CGSize)size scale:(CGFloat)scale orientation:(UIImageOrientation)orientation {
CGFloat maxPixelSize = MAX(size.width, size.height);
CGImageSourceRef ref = CGImageSourceCreateWithData((__bridge CFDataRef)data, nil);
NSDictionary *options = @{(__bridge id)kCGImageSourceCreateThumbnailFromImageAlways:(__bridge id)kCFBooleanTrue,(__bridge id)kCGImageSourceThumbnailMaxPixelSize:[NSNumber numberWithFloat:maxPixelSize]};
CGImageRef imageRef = CGImageSourceCreateThumbnailAtIndex(ref, 0, (__bridge CFDictionaryRef)options);
UIImage *resultImage = [UIImage imageWithCGImage:imageRef scale:scale orientation:orientation];
CGImageRelease(imageRef);
CFRelease(ref);
return resultImage;
}
6、大視圖
大視圖是指View的size過大寡润,自身包含要渲染的內容捆憎。比如微信里常見的炸群消息,通常幾千甚至幾萬行梭纹。如果把它繪制到同一個View里躲惰,那將會消耗大量內存,同時造成嚴重卡頓变抽。最好做法是把文本劃分成多個View繪制礁扮,利用TableView的復用機制知举,減少不必要的渲染和內存占用。