• <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++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理
            原文:http://blog.csdn.net/weiqubo/article/details/8152326

            由init、loadView、viewDidLoad、viewDidUnload、dealloc的關系說起

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

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

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

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

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

             

            self.myOutlet = nil;

             

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

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

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

            其實兩者最大的區別就是: viewDidUnload 是內存除當前以外所有 viewController 同時執行,而 dealloc 只是當前 viewController 執行。這個是網上的材料沒有說明的。

            個人拙見,不對之處還請提正!

            PS: 很多朋友都說無法調試 viewDidUnload,其實是可以的。方法是在 iOS 模擬器的菜單里選 硬件->模擬內存警告,這個時候就可以看到 viewDidUnload 里面 NSLog 的東西了,可以試試在打開過的 viewController 里都 NSLog 一下看看效果。而 dealloc 里面可以直接 NSLog。



            由init、loadView、viewDidLoad、viewDidUnload、dealloc的關系說起

            init方法

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

            init方法中初始化ViewController本身

             loadView方法

            當view需要被展示而它卻是nil時,viewController會調用該方法。不要直接調用該方法。

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

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

            loadView和IB構建view

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

             

            viewDidLoad方法

            viewDidLoad 此方法只有當view從nib文件初始化的時候才被調用。

            重載重寫該方法以進一步定制view

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

            viewDidLoad后調用數據Model

            viewDidUnload方法

            當系統內存吃緊的時候會調用該方法(注:viewController沒有被dealloc)

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

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

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

            一般認為viewDidUnload是viewDidLoad的鏡像,因為當view被重新請求時,viewDidLoad還會重新被執行

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

            dealloc方法

            viewDidUnload和dealloc方法沒有關聯,dealloc還是繼續做它該做的事情

            看到以下的代碼

            - (void)viewDidUnload {

            self.detailViewController = nil; 

            self.languageNames = nil; 

            self.languageCodes = nil;

            }

            - (void)dealloc {

            [detailViewController release];

             [languageNames release]; 

            [languageCodes release]; 

            [super dealloc];

            }


            如果是先調用viewDidUnload后再調用dealloc, 那么languageNames都已經是nil了,再掉release有什么意義呢?
            原 因似乎是, 對一個viewcontroller來說,它的數據的初始化在init中,而它管理的view采用了lazy load的方式,也就是有需要的時候才會載入, 所以跟view相關的數據可以在viewDidLoad(也就是在view被載入的時候)進行初始化。當內存緊張的時候, ios會銷毀點一些view, 通過調用viewDidUnload (里面一般也只是把跟view相關的數據設為nil), 但這個時候viewcontroller本身還在, 所以它的dealloc不會被調用,除非是到了viewcontroller也被銷毀的時候
            成人综合伊人五月婷久久| 久久天堂电影网| 7国产欧美日韩综合天堂中文久久久久 | 亚洲精品白浆高清久久久久久| 中文字幕一区二区三区久久网站| 99精品久久精品一区二区| 久久无码专区国产精品发布| 久久精品成人免费观看97| 91亚洲国产成人久久精品| 久久精品嫩草影院| 久久精品国产免费一区| 国产高潮国产高潮久久久| 99国产欧美久久久精品蜜芽| 国产精品免费看久久久| 97久久超碰国产精品2021| 久久99亚洲网美利坚合众国| 久久久久无码精品国产不卡| 久久久久亚洲Av无码专| 国产精品一区二区久久| 久久久久四虎国产精品| 91精品国产91热久久久久福利| 久久成人精品视频| 精品久久人人妻人人做精品| 久久精品国产亚洲av瑜伽| 人妻无码久久精品| 97久久婷婷五月综合色d啪蜜芽| 亚洲精品乱码久久久久久蜜桃图片 | 国产91久久综合| 久久人人爽人人爽人人片AV东京热 | 日产精品久久久久久久性色| 亚洲第一极品精品无码久久| 国产三级久久久精品麻豆三级| 久久精品男人影院| 色婷婷久久久SWAG精品| 无码AV中文字幕久久专区| 久久99精品国产99久久6男男| 国产精品日韩深夜福利久久| 手机看片久久高清国产日韩| 久久99国产综合精品女同| 久久久久人妻一区精品| 久久久亚洲欧洲日产国码二区|