1. <thead id="4fq7u"></thead>
    2. <th id="4fq7u"><address id="4fq7u"></address></th>
        <object id="4fq7u"></object>
      1. 徐州酷優網絡 開啟企業建站營銷新時代  站長學院 Loading
        熱線:0516-83703228
        您現在的位置:首頁 > 站長學院 > 小程序

        APP開發之使用Analyze和Instruments工具解決內存泄漏問題

        作者:admin 日期:2021/12/16 15:07:46 人氣:32

          

        內存泄漏指一個對象或變量在使用完成后沒有釋放掉,這個對象一直占用這部分內存,直到應用停止。如果這種對象過多,內存就會耗盡,其他應用就無法運行。這個在問題C++、C和Objective-C的MRC中是比較普遍的問題。

        在Objective-C中,釋放對象的內存時,可以發送release和autorelease消息,它們都可以將引用計數減1。當引用計數為0時,release消息會使對象立刻釋放,autorelease消息會將對象放入內存釋放池中延遲釋放。

        下面徐州APP制作開發公司-百恒網絡為您介紹一下Objective-C工程中ViewController的代碼片段:

        Objective-C工程中ViewController的代碼片段一

        Objective-C工程中ViewController的代碼片段二

        大家看看,上面的這3個方法會有什么問題呢?如果代碼基于ARC,這是沒有問題的,但遺憾的這是基于MRC的,都存在內存泄漏的可能性。從理論上講,內存泄漏是由對象或變量沒有釋放引起的,但實踐證明并非所有的未釋放對象或變量都會導致內存泄漏,這與硬件環境和操作系統環境有關,因此我們需要檢測工具幫助我們找到這些“泄漏點”。

        在Xcode中,共提供了兩種工具幫助查找泄漏點:Analyze和Instruments。Analyze是靜態分析工具??梢酝ㄟ^Product→Analyze菜單項啟動。圖1所示為使用Analyze工具進行靜態分析之后的代碼界面。Instruments是動態分析工具,它與Xcode集成在一起,可以在Xcode中通過Product→Profile菜單項啟動。如圖2所示,Instruments有很多跟蹤模板可以動態分析和跟蹤內存、CPU和文件系統。

        使用Analyze進行靜態分析的代碼界面

        Instruments分析工具

        我們可以結合使用這兩個工具查找泄漏點。先使用Analyze靜態分析查找可疑泄漏點,再用Instruments動態分析中的Leaks和Allocations跟蹤模板進行動態跟蹤分析,確認這些點是否泄漏,或者是否有新的泄漏出現等。

        在圖1所示的Analyze靜態分析結果中,凡是有圖標的行都是工具發現的疑似泄漏點。點擊viewDidLoad方法中疑似泄漏點行末尾的圖標,會展開分析結果,具體如圖3所示。

        viewDidLoad方法的疑似泄漏點展開結果

        圖3中的線表明了程序執行的路徑。在這個路徑中,第1處說明在第25行中,Objective-C對象的引用計數是1,說明在這里創建了一個Objective-C對象。第2處說明在第27行中引用計數為1,該對象沒有釋放,懷疑有泄漏。這樣的說明已經很明顯地告訴我們問題所在了,[[NSArray alloc] initWithContentsOfFile:plistPath]創建了一個對象,并賦值給listTeams屬性所代表的成員變量,然而完成了賦值工作之后,創建的對象并沒有顯式地發送release和autorelease消息。這里可以將代碼修改如下:

        NSArray *array = [[NSArray alloc] initWithContentsOfFile:plistPath];

        self.listTeams = array;

        [array release];

        點擊tableView:cellForRowAtIndexPath:方法中疑似泄漏點行末尾的圖標,展開分析結果,如圖4所示。

        tableView:cellForRowAtIndexPath:方法的疑似泄漏點展開結果

        這主要說明UITableViewCell *類型的cell對象在第64行有可能存在泄漏。在表視圖中,tableView:cellForRowAtIndexPath:方法用于實例化表視圖單元格并設置數據,因此cell對象實例化后不能馬上釋放,而應該使用autorelease延遲釋放??梢栽趧摻╟ell對象時發送autorelease消息,將代碼修改如下:

        if (cell == nil) {

        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault

        reuseIdentifier:CellIdentifier] autorelease];

        }

        我們再看一下tableView:didSelectRowAtIndexPath:方法中的疑似泄漏點,共有兩個。點擊行末尾的圖標,展開分析結果,具體如圖5和圖6所示。

        圖5 tableView:didSelectRowAtIndexPath:方法疑似泄漏點1的展現結果 圖6 tableView:didSelectRowAIndexPath:方法疑似泄漏點2的展開結果

        圖5所示的是message對象創建之后沒有釋放,我們只需要在[alert show]之后添加[message release]語句代碼就可以了。

        在Objective-C中,實例化對象有如下兩種方式:

        NSString *message = [[NSString alloc] initWithFormat:@'您選擇了%@隊。', rowValue]; ①

        NSString *message = [NSString stringWithFormat:@'您選擇了%@隊。', rowValue]; ②

        第①行所示的以init開頭的構造方法在alloc之后調用,我們將其稱為“實例構造方法”。對于使用該方法創建的對象,其所有權是調用者,調用者需要對它的生命周期負責,具體說就是負責創建和釋放。第②行所示的以string開頭的方法,它通過類直接調用,我們將其稱為“類級構造方法”。對于使用該方法創建的對象,其所有權非調用者所有,調用者無權釋放它,否則就會因過度釋放而“僵尸化”。

        圖6所示的是UIAlertView *類型的alert對象創建后沒有釋放,我們只需要在[alert show]之后添加[alertrelease]語句就可以了。修改之后的代碼如下:

        UIAlertView *類型的alert對象創建后沒有釋放

        上面介紹的是使用Analyze靜態分析查找可疑泄漏點。之所以稱為“可疑泄漏點”,是因為這些點未必一定泄漏。確認這些點是否泄漏,還要通過Instruments動態分析工具中的Leaks和Allocations跟蹤模板。Analyze靜態分析只是一個理論上的預測過程。在Xcode中通過Product→Profile菜單項啟動Instruments動態分析工具,接著選擇Leaks模板,打開的界面如圖7所示。

        Instruments的Leaks模板

        在Instruments中,雖然選擇了Leaks模板,但默認情況下也會添加Allocations模板?;旧戏彩欠治鰞却娑紩褂肁llocations模板,它可以監控內存分布情況。選中Allocations模板(圖中①區域),右邊的③區域會顯示隨著時間的變化內存使用的折線圖,同時在④區域會顯示內存使用的詳細信息以及對象分配情況。點擊Leaks模板(圖中②區域),可以查看內存泄漏情況。如圖8所示,如果在③區域有紅線出現,則有內存泄漏,④區域則會顯示泄漏的對象。

        Instruments檢測到的內存泄漏

        圖8中出現的泄漏是在點擊表視圖中單元格測試tableView:didSelectRowAtIndexPath:方法時發生的,點擊泄漏對象Address列后面的按鈕,會進入如圖9所示的詳細界面??梢园l現,里面有兩個對象,可以看到它們的內存地址、占用字節、所屬框架和響應方法等信息。

        查看泄露的詳細信息

        在圖9中,點擊右邊的跟蹤堆棧信息按鈕,如圖10所示,其中圖標所示的條目是我們自己應用的代碼,點擊它即可進入程序代碼,如圖11所示。

        圖10 查看堆棧信息 圖11 查看泄漏點

        圖11所示的第84行代碼是可能的泄漏點。事實上,內存泄漏是極其復雜的問題,工具使用是一方面,經驗是另一方面。提高經驗,然后借助于工具才是解決內存泄漏的根本。


        回到頂部
        亚洲精品tv久久久久久久|久久精品2019中文字幕|精品无码国产一区二区三区51安|天天碰夜夜摸公开视频