什么是內存泄漏
內存泄漏就是你申請了一份內存萍程,但是由于某種原因骏庸,程序未釋放或無法釋放,造成系統(tǒng)內存的浪費。
造成內存泄漏原因是什么
現(xiàn)在一般都是ARC環(huán)境褐澎,所以造成內存泄漏的原因主要是強引用循環(huán),還有就是添加的一些觀察者沒有解除觀察这吻。
如何發(fā)現(xiàn)內存泄露
即使我們在編寫程序的時候格外注意了琳轿,但還是無法100%保證我們代碼沒有造成內存泄漏,這時候怎么檢測呢转培?不要慌恶导,蘋果還是很貼心的,Xcode給我們提供一系列的開發(fā)工具浸须,其中Leaks就是用來檢測內存泄漏的惨寿。
如何使用Leaks
工具通過Xcode工具欄中Product->Profile(command+i)或者通過Xcode->Open Developer Tool->Instruments開打Instruments
找到Leaks并打開,然后點擊右上角紅色按鈕運行删窒;
然后把玩你的App裂垦,在內存泄漏的地方,會有紅色的X標記肌索,此時點擊左上角暫停蕉拢;
我們選擇左側Leaks,下面控制臺的菜單欄也選擇Leaks(默認是Run Issue)诚亚,然后選擇Call Tree晕换。如圖
最下面Call Tree勾選Invert Call Tree和Hide System Libraries
(注:如果做完這幾步,控制臺依然沒有顯示相關代碼站宗,我們打開Xcode->TARGETS->Build Settings搜索Debug Information Format届巩,將debug和release都設置為DWARF with dSYM File即可)
這里有兩處內存泄漏的地方,我們要分別查看的話份乒,可以鼠標點擊X的左邊恕汇,然后拖動腕唧,選中X的區(qū)域。然后控制臺就會出現(xiàn)內存泄漏的相關代碼瘾英,雙擊會定位到代碼的位置枣接。點擊右上角xcode小圖標會在xcode里面打開。如下圖缺谴,不僅標記了位置但惶,還注明了泄漏的內存大小。
經(jīng)過排查我們發(fā)現(xiàn)所有的內存泄漏都是AFNetWorking造成的湿蛔。這并不是檢測方法不對膀曾,而是AFNetWorking確實存在內存泄漏。我們仔細看這段代碼阳啥。
這里的self是AFURLSessionManager添谊,self強引用了session,而self作為delegate傳給了session察迟。我們點擊sessionWithConfiguration:delegate: delegateQueue:方法后發(fā)現(xiàn)斩狱,蘋果為了確保網(wǎng)絡數(shù)據(jù)的正常使用,session對他的delegate是強引用扎瓶。也就是self與session相互強引用所踊。
我們都知道代理需要用弱引用,但是這里破例用了強引用概荷,所以造成強引用循環(huán)秕岛,導致無法釋放。
官方的文檔里解釋了為什么會強引用代理误证,也給出如何解決這個強引用循環(huán)的問題瓣蛀。
If you do not invalidate the session by calling the invalidateAndCancel or finishTasksAndInvalidate method, your app leaks memory until it exits.
意思就是我們可以通過調用invalidateAndCancel或者finishTasksAndInvalidate這兩個方法來釋放session
于是我們代碼改成
NSURLSession *session = self.sessionManager.session;
NSURLSessionDataTask *dataTask = [self.sessionManager GET:url parameters:self.params progress:^(NSProgress * _Nonnull downloadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"請求成功:\n%@",responseObject);
[session finishTasksAndInvalidate];
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"請求失敗:\n%@",error);
[session finishTasksAndInvalidate];
}];
[dataTask resume];
改完之后再次通過Leaks檢測雷厂,看到一片綠惋增,心情一下舒暢許多