• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 319, comments - 22, trackbacks - 0, articles - 11
              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理
            原文:http://blog.csdn.net/weiqubo/article/details/8152326

            由init、loadView、viewDidLoad、viewDidUnload、dealloc的關(guān)系說起

            分類: iOS 273人閱讀 評論(0) 收藏 舉報

            對于iphone開發(fā)人員來說,內(nèi)存管理是極為重要的技巧,哪怕程序的功能再強大,設(shè)計再漂亮,如果內(nèi)存控制不好,也難逃程序莫名退出的噩運,這與網(wǎng)頁開發(fā)是完全不同的。

            內(nèi)存控制里面有很多門道,在這里分析一下 viewDidUnload 和 dealloc 的區(qū)別,關(guān)于這兩者的區(qū)別的文章很多,但是大都是摘抄和翻譯官方文檔,有的也只是簡單的說兩句,并沒有詳細(xì)說出兩者具體的區(qū)別。

            在了解兩者之間的區(qū)別,首先要知道 view 的生命周期,google 里面有很多文章,可以先去搜一下,這里就不詳解了。

            顧名思義  viewDidUnload 就是當(dāng) view 被卸載以后執(zhí)行的語句,它與 viewDidLoad 是相互呼應(yīng)的。大家都知道官方的解釋是執(zhí)行類似

             

            self.myOutlet = nil;

             

            的命令,但是為什么這么干,什么時候調(diào)用這個方法呢?

            這個方法是不能手動調(diào)用的,它實際上是當(dāng)應(yīng)用程序接收到手機內(nèi)存警告的時候自動調(diào)用的方法,目的就是清空內(nèi)存除當(dāng)前 viewController 以外所有已經(jīng)加載過的 viewController 里面的暫時不再使用的一些控件或數(shù)據(jù),以避免應(yīng)用程序應(yīng)消耗內(nèi)存過多被強制關(guān)閉。記住,是除當(dāng)前正在展示的 view 所屬 viewController 以外所有已經(jīng)在內(nèi)存里面的 viewController 執(zhí)行 viewDidUnload 方法, 而不是當(dāng)前 viewController 執(zhí)行 viewDidUnload,當(dāng)然,這些 viewController 不會被 dealloc。所以在 viewDidUnload 里面一般都是釋放 IBOutlet 變量和在 viewDidLoad、viewWillAppear、viewDidAppear 等方法能夠重建的數(shù)據(jù)。而由其他頁面?zhèn)鬟f過來的數(shù)據(jù)或者無法經(jīng)過 viewDidLoad、viewWillAppear、viewDidAppear 等方法重建的數(shù)據(jù)則不能釋放,舉例子說如果在 navigationController 由上一個頁面?zhèn)鬟f過來的一張圖片,在 viewDidUnload 里被釋放的話,則當(dāng) view 再次加載的時候就無法恢復(fù)了。

            那為什么要寫成 self.myOutlet = nil; ,實際上這個語法是執(zhí)行了 property 里的setter 方法,而不是一個簡單的變量賦值,它干了兩件事:1、老數(shù)據(jù) release 掉,2、新數(shù)據(jù)(nil)retain(當(dāng) property 設(shè)置為 retain 的情況下),當(dāng)然對 nil retain 是無意義的。如果寫成 myOutlet = nil,那就是簡單的把 myOutlet 指向 nil,這樣內(nèi)存就泄漏了,因為老數(shù)據(jù)沒有 release。而如果僅僅寫成 [myOutlet release] 也會有問題,因為當(dāng) view 被 dealloc 的時候會 再次 release,程序就出錯了,而對 nil release 是沒有問題的。
             
            dealloc 是當(dāng)前 viewController 被釋放的時候,清空所有當(dāng)前 viewController 里面的實體和數(shù)據(jù)來釋放內(nèi)存,該方法也是自動調(diào)用的,無需手動執(zhí)行。舉例說明當(dāng) modalView 被 dismissModalViewControllerAnimated 或者 navigationController 回到上一頁的時候,這個方法就會被自動調(diào)用。因為這個頁面已經(jīng)不再使用了,所以可以把所有實體和數(shù)據(jù)都釋放(release)掉。

            其實兩者最大的區(qū)別就是: viewDidUnload 是內(nèi)存除當(dāng)前以外所有 viewController 同時執(zhí)行,而 dealloc 只是當(dāng)前 viewController 執(zhí)行。這個是網(wǎng)上的材料沒有說明的。

            個人拙見,不對之處還請?zhí)嵴?br />
            PS: 很多朋友都說無法調(diào)試 viewDidUnload,其實是可以的。方法是在 iOS 模擬器的菜單里選 硬件->模擬內(nèi)存警告,這個時候就可以看到 viewDidUnload 里面 NSLog 的東西了,可以試試在打開過的 viewController 里都 NSLog 一下看看效果。而 dealloc 里面可以直接 NSLog。



            由init、loadView、viewDidLoad、viewDidUnload、dealloc的關(guān)系說起

            init方法

            在init方法中實例化必要的對象(遵從LazyLoad思想)

            init方法中初始化ViewController本身

             loadView方法

            當(dāng)view需要被展示而它卻是nil時,viewController會調(diào)用該方法。不要直接調(diào)用該方法。

            如果手工維護(hù)views,必須重載重寫該方法

            如果使用IB維護(hù)views,必須不能重載重寫該方法

            loadView和IB構(gòu)建view

            你在控制器中實現(xiàn)了loadView方法,那么你可能會在應(yīng)用運行的某個時候被內(nèi)存管理控制調(diào)用。 如果設(shè)備內(nèi)存不足的時候, view 控制器會收到didReceiveMemoryWarning的消息。 默認(rèn)的實現(xiàn)是檢查當(dāng)前控制器的view是否在使用。 如果它的view不在當(dāng)前正在使用的view hierarchy里面,且你的控制器實現(xiàn)了loadView方法,那么這個view將被release, loadView方法將被再次調(diào)用來創(chuàng)建一個新的view。

             

            viewDidLoad方法

            viewDidLoad 此方法只有當(dāng)view從nib文件初始化的時候才被調(diào)用。

            重載重寫該方法以進(jìn)一步定制view

            在iPhone OS 3.0及之后的版本中,還應(yīng)該重載重寫viewDidUnload來釋放對view的任何索引

            viewDidLoad后調(diào)用數(shù)據(jù)Model

            viewDidUnload方法

            當(dāng)系統(tǒng)內(nèi)存吃緊的時候會調(diào)用該方法(注:viewController沒有被dealloc)

            內(nèi)存吃緊時,在iPhone OS 3.0之前didReceiveMemoryWarning是釋放無用內(nèi)存的唯一方式,但是OS 3.0及以后viewDidUnload方法是更好的方式

            在該方法中將所有IBOutlet(無論是property還是實例變量)置為nil(系統(tǒng)release view時已經(jīng)將其release掉了)

            在該方法中釋放其他與view有關(guān)的對象、其他在運行時創(chuàng)建(但非系統(tǒng)必須)的對象、在viewDidLoad中被創(chuàng)建的對象、緩存數(shù)據(jù)等 release對象后,將對象置為nil(IBOutlet只需要將其置為nil,系統(tǒng)release view時已經(jīng)將其release掉了)

            一般認(rèn)為viewDidUnload是viewDidLoad的鏡像,因為當(dāng)view被重新請求時,viewDidLoad還會重新被執(zhí)行

            viewDidUnload中被release的對象必須是很容易被重新創(chuàng)建的對象(比如在viewDidLoad或其他方法中創(chuàng)建的對象),不要release用戶數(shù)據(jù)或其他很難被重新創(chuàng)建的對象

            dealloc方法

            viewDidUnload和dealloc方法沒有關(guān)聯(lián),dealloc還是繼續(xù)做它該做的事情

            看到以下的代碼

            - (void)viewDidUnload {

            self.detailViewController = nil; 

            self.languageNames = nil; 

            self.languageCodes = nil;

            }

            - (void)dealloc {

            [detailViewController release];

             [languageNames release]; 

            [languageCodes release]; 

            [super dealloc];

            }


            如果是先調(diào)用viewDidUnload后再調(diào)用dealloc, 那么languageNames都已經(jīng)是nil了,再掉release有什么意義呢?
            原 因似乎是, 對一個viewcontroller來說,它的數(shù)據(jù)的初始化在init中,而它管理的view采用了lazy load的方式,也就是有需要的時候才會載入, 所以跟view相關(guān)的數(shù)據(jù)可以在viewDidLoad(也就是在view被載入的時候)進(jìn)行初始化。當(dāng)內(nèi)存緊張的時候, ios會銷毀點一些view, 通過調(diào)用viewDidUnload (里面一般也只是把跟view相關(guān)的數(shù)據(jù)設(shè)為nil), 但這個時候viewcontroller本身還在, 所以它的dealloc不會被調(diào)用,除非是到了viewcontroller也被銷毀的時候
            精品国产福利久久久| 伊人色综合久久| 久久免费观看视频| 办公室久久精品| 久久精品国产第一区二区三区 | 久久久久久久国产免费看| 午夜不卡888久久| 狠狠干狠狠久久| 精品人妻伦九区久久AAA片69| 久久免费99精品国产自在现线| 狠狠色婷婷久久综合频道日韩| 嫩草影院久久99| 欧美噜噜久久久XXX| 久久天天日天天操综合伊人av| 波多野结衣中文字幕久久| 老司机午夜网站国内精品久久久久久久久| 久久精品国产乱子伦| 久久高清一级毛片| 久久久久国产精品| 久久精品亚洲中文字幕无码麻豆 | 2021国产精品久久精品| 久久国产乱子伦精品免费午夜| 久久AV高潮AV无码AV| 久久久久18| 国产精品无码久久四虎| 久久精品国产清高在天天线| 无码专区久久综合久中文字幕| 久久夜色精品国产| 久久天天躁狠狠躁夜夜2020老熟妇| 久久综合综合久久97色| 久久91综合国产91久久精品| 国产精品99精品久久免费| 精品少妇人妻av无码久久| 午夜精品久久久久久99热| 久久亚洲AV成人无码软件| 香蕉久久夜色精品国产2020| 欧美久久久久久| 日日躁夜夜躁狠狠久久AV| 久久丫精品国产亚洲av| 嫩草伊人久久精品少妇AV| 99久久99久久精品免费看蜜桃|