IOS viewDidLoad方法被執行兩次(viewDidLoad和loadView方法詳解)
為了搞清楚viewDidLoad、loadView等方法的用途和呼叫順序,寫了一個小demo,不料viewDidLoad方法被執行了兩次,模擬器也一直是黑屏。查看了這兩個方法的官方解釋後找到了錯誤原因和解決方法。
首先來看UIViewController.h檔案中對viewDidLoad方法的解釋:
- (void)viewDidLoad;
// Called after the view has been loaded. For view controllers created in code, this is after -loadView. For view controllers unarchived from a nib, this is after the view is set.
接下來是對loadView方法的解釋:
- (void)loadView;
// This is where subclasses should create their custom view hierarchy if they aren't using a nib. Should never be called directly.
無論是從xib檔案中載入檢視,還是自己建立檢視,viewDidLoad方法都會被呼叫,而且都是在檢視已經被載入後呼叫,所以這裡可以明確的一點是,任何UI控制元件的建立都不應該在viewDidLoad方法中被實現,因為這是xib檔案或者loadView方法的任務。viewDidLoad只是通過nib或者loadView方法載入檢視的一週拓展和補充機制,比如一些不方便通過nib設定的屬性或是臨時需要進行處理的控制元件內容。
至於loadView方法和xib檔案的關係,個人的理解是:真正的UI控制元件的建立,都是要通過呼叫loadView中的程式碼來實現的,只不過在xib檔案中,這些程式碼以xml格式的文件被儲存,並且蘋果通過storyboard解析這個xml文件,形成了一個視覺化的圖形介面。這是兩者的共同點,至於不同點,官方文件中的解釋已經很清楚了,一旦呼叫了loadView方法就意味著不是用nib檔案。這就意味著loadView和xib檔案不相容。loadView具有更高的優先順序。
下面通過幾個實驗來證明以上觀點。
實驗1:
建立一個空的工程檔案,在viewDidLoad函式中寫入簡單的一行程式碼:
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"123");
}
實驗結果:執行程式後發現:控制檯輸出一行結果“123”。模擬器顯示一個純白色的介面。
實驗分析:控制檯的結果非常容易理解。但是我們並沒有建立一個UIView或者設定它的背景顏色,系統是怎麼建立我們在模擬器中看到的內容的呢?
答案是,如果我們不實現loadView方法,系統會預設我們不適用自定義的方式建立view而是從nib檔案中載入。這時候就回去storyboard或者其他相應的nib檔案中去尋找載入檢視的程式碼。由於預設的ViewController類在main.storyboard中有自己的nib檔案,所以可以成功的載入一個UIView。
實驗2:
實現一個空的loadView方法:
- (void)loadView{
}
實驗結果:執行程式後發現,控制檯輸出兩行“123”,模擬器黑屏。
實驗分析:模擬器黑屏非常容易理解,因為我們實現了loadView方法,編譯器以為我們要自定義一個UIView物件,從而去執行loadView方法中的程式碼,試圖建立一個UIView,但是顯然這樣做會失敗,所以得到一個黑色的(沒有任何內容)的介面。至於為什麼viewDidLoad方法會被呼叫兩次,原因並不清楚(希望讀到此處的大牛留言指教)。
實驗三:
實現完整的loadView方法:
- (void)loadView{
self.view = [[ UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
self.view.backgroundColor = [UIColor whiteColor];
}
實驗結果:同實驗1的結果
實驗分析:實現了一個完整的UIView的建立過程,與通過nib檔案建立非常類似。
通過以上幾個實驗得出以下結論:
1.如果想要通過自定義的程式碼建立UIView,把這些程式碼都寫入loadView方法裡面去。
2.希望通過nib檔案建立UIView的話,不要重寫loadView方法。
3.viewDidLoad方法被執行兩次很有可能是重寫了一個不完整的loadView方法導致的 。
相關推薦
IOS viewDidLoad方法被執行兩次(viewDidLoad和loadView方法詳解)
為了搞清楚viewDidLoad、loadView等方法的用途和呼叫順序,寫了一個小demo,不料viewDidLoad方法被執行了兩次,模擬器也一直是黑屏。查看了這兩個方法的官方解釋後找到了錯誤原因和解決方法。 首先來看UIViewController.h檔
thinkphp中方法被執行兩次
最近兩天程式碼中出現了一個問題,就是我的控制器的方法中執行了向資料庫插入,每次點開該頁面,add()方法就會被執行兩次,就是因為這個add方法讓我發現此方法被執行了兩次,因為每次點開該頁面,資料庫就會增加兩條記錄。
支付寶面試題: 30秒內限制某方法被呼叫100次 (一個時間段限制方法被呼叫的次數)
假設一個Class的方法 a,被限定30秒內只能被呼叫100次,如何實現。 當時沒答上,回來補上 1、定義呼叫介面Icallee public interface Icallee {public void play(); } 2、實現呼叫介面類 publi
spring定時任務執行兩次的原因與解決方法
ref net 任務 article 服務 每次 bsp tail 本地 spring定時任務,本地執行一次,放到服務器上後,每次執行時會執行兩次,原因及解決辦法。 http://blog.csdn.net/yaobengen/article/details/70312
struts2,action方法自動執行兩次
sys sele urn 自動 obj sel hiberna ron name 發現一個比較有意思的bug, //Action中以get開頭且返回類型不為void(如 public Object get*() )的方法會被自動執行//放入值棧時會執行一次,//若在頁面調
Android多程序app中Application回撥onCreate()方法被執行多次分析及解決
最近工作中碰到一個問題,在優化app,使用DDMS檢視Application log過程中看到,app啟動了三個程序,一個主程序,兩個附帶的程序。如下圖可看到一個app啟動的三個程序。 自定義Application回撥方法onCreate()被執行了3次。開始不知是何原因。 相
Tomcat 啟動兩次的問題(ServletContextListener的contextInitialized被執行兩次的問題)
問題: 在啟動 tomcat5 時,控制檯視窗會打印出兩行“hello word”字串? 問題原因: 因為hello應用本來就放在Tomat的預設webapp目錄下(tomcat在啟動時肯定會載入1次),然後又在server.xml中做了配置,為了達到訪問根就可以訪問hello應用
RadioGroup呼叫check(id)方法時,onCheckedChanged方法被執行多次解決辦法
RadioGroup bottomMenuBar = (RadioGroup) findViewById(R.id.bottomMenuBar); bottomMenuBar.setOnCheckedChangeListener(this); bottomMenuBar.c
Java Web開發中,自定義過濾器被執行兩次的原因分析及解決辦法
本文出處:http://blog.csdn.net/chaijunkun/article/details/7646338,轉載請註明。由於本人不定期會整理相關博文,會對相應內容作出完善。因此強烈建議在原始出處檢視此文。 在Java Web開發過程中,我們可以使用過濾器和Sp
Android 經典筆記之一:setOnKeyListener方法事件執行兩次
Android 經典總結案例一 目錄介紹: 1.完美解決onActivityResult提前執行呼叫的一系列問題 1.1 出現的問題 1.2 解決方案 1.3 相關原理說明 1.4 知識拓展 2.EditText呼叫軟鍵盤搜尋的setOnKeyListener方
Quartz每次排程時被執行兩次
[關鍵字:重複執行、重複呼叫、每次執行兩次、執行2次]前言: 先說一下,專案背景。由於組內某成員在用Maven搭建專案時不規範,導致專案的名稱與實際訪問專案名稱不一致。在部署專案時,必需要配一下虛擬路徑,對映到那個專案所在目錄下去,才能正常訪問。舉個例子:專案名稱叫student-web,部署到Tomcat
UI自動化測試(二)瀏覽器操作及對元素的定位方法(xpath定位和css定位詳解)
cli 刷新 ota api enter 版本 ror apache 窗口 Selenium下的Webdriver工具支持FireFox(geckodriver)、 IE(InternetExplorerDriver)、Chrome(ChromeDriver)、 Opera
InnoDB的關鍵特性-插入快取,兩次寫,自適應hash索引詳解
InnoDB儲存引擎的關鍵特性包括插入緩衝、兩次寫(double write)、自適應雜湊索引(adaptive hash index)。這些特性為InnoDB儲存引擎帶來了更好的效能和更高的可靠性。插入緩衝插入緩衝是InnoDB儲存引擎關鍵特性中最令人激動的。不過,這個名字
自定義一個更好用的SwipeRefreshLayout(彈力拉伸效果詳解)(轉載)
dsc drag 常數 lane swipe loading 數據改變 高中數學 tca 轉自: 自定義一個更好用的SwipeRefreshLayout(彈力拉伸效果詳解) 前言 熟悉SwipeRefreshLayout的同學一定知道,SwipeRefreshLayout是
CentOS6.5下Cloudera安裝搭建部署大數據集群(圖文分五大步詳解)(博主強烈推薦)
centos6 數據 http 時間 log .com pos OS 客戶端 第一步: Cloudera Manager安裝之Cloudera Manager安裝前準備(CentOS6.5)(一) 第二步: Cloudera Manager安裝之時間服務器和
函數的特點,應用,重載等講解(代碼加理論詳解)!
學生 打印 ext 錯誤 如果 ron sta urn double 函數的特點:1、定義函數可以將功能代碼進行封裝2、便於對該功能進行復用3、函數只有被調用才會被執行4、函數的出現提高了代碼的復用性5、對於函數沒有具體返回值的情況,返回值類型用關鍵字void表示,那麽該函
SELECT is not allowed in cluster (Redis叢集JedisCluster資料庫詳解)
(1)redis在單機模式下redis.conf配置檔案中預設的資料庫數量是16個, # Set the number of databases. The default database is DB 0, you can select# a different one on
Linux(vi/vim命令使用詳解)
vi test.txt 或者 vim test.txt 再或者 touch test.txt vim是vi的升級版,指令更多,功能更強。 下面是收集的vim用法,當在vim裡面要實現退出,首先要做的是按【Esc】,然後再輸入【:wq】 一、一般模式:
LNMP架構四(php-fpm的配置詳解)
四、php-fpm的配置詳解 和LAMP不同的是,在LNMP架構中,php-fpm作為獨立的一個服務存在,既然是獨立服務,那麼它必然有自己的配置檔案。php-fpm的配置檔案為/usr/local/php-fpm/etc/php-fpm.conf,它同
類和物件-中(6個預設函式詳解)
本文主要是對類的6個預設函式進行講解 類的預設成員函式有6個:建構函式 解構函式