1、運行MemoryProblems后皿淋,運行崩潰出現(xiàn)EXC_BAD_ACCESS,啟動NSZombieEnabled恬试,選中Edit Scheme并點擊窝趣,Run -> Diagnostics -> Enable Zombie Objects(懸掛指針的檢測),設置完之后训柴,再次運行和點擊頁面哑舒,雖然會再次crash,但這次控制臺打印了有用信息幻馁,點擊Continue program execution按鈕繼續(xù)運行洗鸵,對比找到相同地址并修改(啟動MallocStackLogging)
常見原因:某變量被assign修飾,對變量值后宣赔,它的對象就馬上釋放预麸,而變量也不是strong而是weak,此時仍然使用就會導致程序crash
2儒将、手動靜態(tài)分析:應用Product—>Analyze或快捷鍵shift + command + b進行內(nèi)存泄漏的初步檢測
????自動靜態(tài)分析:在Build Settings啟用Analyze During 'Build'吏祸,每次編譯時都會自動靜態(tài)分析
3、可以在xcode的build setting中打開implicit retain of ‘self’ within blocks钩蚊,xcode編譯器會給出警告贡翘,逐個排查警告
4、應用Leak Instrument進行內(nèi)存泄露查找:點擊Xcode的菜單欄的?Product?->?Profile?啟動Instruments砰逻,出現(xiàn)Instruments的工具集鸣驱,選中Leaks子工具點擊,點擊紅色圓點按鈕啟動Leaks工具蝠咆,在Leaks工具啟動同時踊东,模擬器或真機也跟著啟動,啟動Leaks工具后刚操,它會在程序運行時記錄內(nèi)存分配信息和檢查是否發(fā)生內(nèi)存泄露
首先點擊Leak Checks時間條那個紅色叉闸翅,點擊紅色叉后,下面顯示Leaks By Backtrace菊霜,雙擊某行內(nèi)存泄露調(diào)用棧坚冀,會直接跳到內(nèi)存泄露代碼位置
Leak Instrument有Cycles & Roots界面:Persistent Bytes和#Persistent。#Persistent是object的數(shù)量鉴逞,也就是allocation的次數(shù)记某,而Persistent Bytes是具體的內(nèi)存大小司训。#Persistent是我們需要關注的,內(nèi)存有沒有泄露也是看這個值是不是只增不減液南。
Allocations:啟動Allocations壳猜,勾選列表最上邊的,右邊設置勾選:Discard unrecorded data upon stop贺拣、Identify virtual C++ objects蓖谢、* isContain…Record?
列表勾選VM
Generation Analysis
這個功能是非常有用的,一般是這樣用的:進入一個頁面前mark一下譬涡,在退出這個頁面的時候再mark一下可以比較哪些內(nèi)容增加了闪幽,就可以具體分析哪些內(nèi)存沒有被釋放
Call Tree:需要我們把列表展示類型切換成Call Trees,能夠非常清晰的看到調(diào)用樹
Separate by Category:按照類別隔開涡匀,我們鉤上看看效果
Separate by Thread:按照線程劃分盯腌,我個人不是很喜歡這種劃分,因為我不是很關心線程
Invert Call Tree:反轉(zhuǎn)調(diào)用陨瘩,我們給一張對比圖就不需要解釋了
Hide System Libraries:這個似乎是必鉤的腕够,因為我們目前只關心自己的方法,不關心系統(tǒng)的
Flatten Recursion:扁平化遞歸
Data Mining:數(shù)據(jù)挖掘舌劳,這是一個很具有噱頭的功能
點擊Symbol帚湘、Library會自動把你選中的行的符號、庫加到小框中
符號和庫有兩個選項甚淡,就是是否過濾改行大诸;點擊Restore會去掉小框中的選中行
5、通過查看dealloc是否調(diào)用查看某個class是否泄漏問題
- (void)dealloc
{
?NSLog(@"release XXXXViewController");
}
方法:?__weak?XXXXViewController?*weakSelf =?self;在Block里用weakSelf
常見問題:
1贯卦、UITextField在iOS 11內(nèi)存泄漏問題:UITextField沒釋放原因使用secureTextEntry屬性资柔,解決方案
- (BOOL)textFieldShouldBeginEditing:(UITextField?*)textField {
?if?(textField ==?self.passWordTextField) {
textField.secureTextEntry?=?YES;
}else?{
textField.secureTextEntry?=?NO;
? ? }
?return?YES;
}
2、使用CGMutablePathRef?path =?CGPathCreateMutable();時出現(xiàn)Potential leak of an object stored into 'path’撵割,解決方案
CGPathRelease(path);
以creat,copy作為關鍵字的函數(shù)都是需要釋放內(nèi)存的贿堰,注意配對使用。比如:CGColorCreate<-->CGColorRelease
3啡彬、The 'viewWillDisappear:' instance method in UIViewController subclass?
XXX is missing a [super viewWillDisappear:] callm羹与,解決方案
- (void)viewWillAppear:(BOOL)animated {
[super?viewWillAppear:animated];
}
4、調(diào)用
+ (NSTimer?*)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable?id)userInfo repeats:(BOOL)yesOrNo;
方法之后在不需要NSTimer時及時調(diào)用[self.timer?invalidate];千萬不要在dealloc方法中調(diào)用庶灿,因為NSTimer強引用self注簿,所以不會執(zhí)行dealloc方法。
5跳仿、對象之間的循環(huán)引用:例子:兩個ViewController都需要使用對方,這個時候可以用@class ;?
說明:在 .h 中引入某個類, @class 指的是 當前文件 只是引入類名, 并沒有使用類里面的東西. 想要在 .m 里面使用 類的內(nèi)容的話, 還是要 #import <>, 這種情況跟 上面的對象之間的防止循環(huán)引 有點不一樣
6捐晶、如果是C申請的內(nèi)存菲语,注意new delete妄辩, malloc free的配對處理。
7山上、圖片相關:
緩存:imageNamed:
只需傳入文件名.擴展名即可眼耀。
可以加載bundle中任意位置的圖片,包括main bundle中其他bundle的佩憾。
imageNamed方法創(chuàng)建對象的步驟如下:
7.1根據(jù)圖片文件名在緩存池中查找圖片數(shù)據(jù)哮伟,如存在,則創(chuàng)建對象并返回妄帘;
7.2如果不存在楞黄,則從bundle中加載圖片數(shù)據(jù),創(chuàng)建對象并返回抡驼;
7.3如果相應的圖片數(shù)據(jù)不存在鬼廓,返回nil。
不緩存:imageWithContentsOfFile:
必須傳入圖片文件的全名(全路徑+文件名)致盟。
無法加載Images.xcassets中的圖片碎税。
對于大的圖片且偶爾需要顯示的應放到工程目錄下,不要放到Assets.xcassets中馏锡;并使用imageWithContentsOfFile加載不讓系統(tǒng)緩存
background.image = [UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/*.png"]];
對于經(jīng)常需要展示的小圖片放到Assets.xcassets中讓系統(tǒng)緩存雷蹂,使用imageNamed加載
background.image = [UIImage imageNamed:@"*.png"];
不常用大圖:將imageView.image = [UIImage imageNamed:nameArr[index]];
改為imageView.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:nameArr[index] ofType:@"png"]];
8、出現(xiàn)VM:CG raster data杯道,SDWebImage的問題
需要在Appdelegate中設置一下
[[SDImageCache sharedImageCache] setShouldDecompressImages:NO];
[[SDWebImageDownloader sharedDownloader] setShouldDecompressImages:NO];
[[SDImageCache sharedImageCache] setShouldCacheImagesInMemory:NO];
9匪煌、VM:CoreAnimation
Found out that animation caused by the inner pages.
Inside the pageViewController(viewController that added to the scrollView as a page) on viewWillDisappear:(BOOL)animated method I added this
for (CALayer* layer in [self.view.layer sublayers]) {
? ? ? ? [layer removeAllAnimations];
}
it resolved the problem.
10、@property?(readwrite,?nonatomic,?copy)?NSMutableURLRequest?*request;出現(xiàn)Property of mutable type 'NSMutableURLRequest' has 'copy' attribute; an immutable object will be stored instead蕉饼,解決方案
@property?(readwrite,?nonatomic,?strong)?NSMutableURLRequest?*request;