每日1道題(day2)

UIViewController 的生命周期
答:來源:http://www.cnblogs.com/dahe007/p/6002964.html
一水醋、下面帶 (NSObject)的方法是NSObject提供的方法捻勉。其他的都是UIViewController 提供的方法。

load (NSObject)

initialize (NSObject)

init (NSObject)

initWithCoder

initWithNibName

awakeFromNib (NSObject)

loadView

viewDidLoad

viewWillAppear

updateViewConstraints

viewWillLayoutSubviews

viewDidLayoutSubviews

viewDidAppear

viewWillDisappear

viewDidDisappear

dealloc (NSObject)

didReceiveMemoryWarning

二道伟、load、initialize晨继、init

load俺孙、initialize是繼承的NSObject的方法。這些在其他文章里寫過墓卦,就不詳述了倦春。大體說下。

在main方法還沒執(zhí)行的時(shí)候 就會(huì) 加載所有類落剪,調(diào)用所有類的load方法睁本。

一般會(huì)在load中實(shí)現(xiàn)Method Swizzle。

初始化對(duì)象忠怖,調(diào)用alloc的時(shí)候會(huì)調(diào)用initialize方法呢堰。這個(gè)時(shí)候是分配內(nèi)存。

init方法是在內(nèi)存中創(chuàng)建好對(duì)象凡泣。

三枉疼、 initWithCoder、initWithNibName鞋拟、awakeFromNib

1骂维、initWithCoder、awakeFromNib

initWithCoder:反歸檔贺纲,如果對(duì)象是從文件解析來的 就會(huì)調(diào)用席舍。

awakeFromNib: 從xib或者storyboard加載完畢 會(huì)調(diào)用。
新建UIView的子類并且想在load nib的時(shí)候做一些初始化工作的時(shí)候 可以重寫awakeFromNib哮笆。bundle在load nib后會(huì)給每個(gè)view對(duì)象發(fā)送一個(gè)awakeFromNib消息来颤。

2、用storyboard稠肘,順序:

initialize -> initWithCoder -> awakeFromNib -> loadView

2福铅、用Xib或者純代碼:

如果用[[VC alloc] init] 來初始化:

initialize -> init -> initWithNibName -> loadView

如果用[[VC alloc] initWithNibName:@“VC” bundle:nil] 來初始化:

initialize -> initWithNibName -> loadView

使用Xib來實(shí)現(xiàn)VC的時(shí)候,不要重寫loadView方法项阴。如果重寫了loadView方法滑黔,則Xib中View就會(huì)消失笆包,變成空View。

四略荡、loadView

1庵佣、要重新設(shè)置View的時(shí)候,在loadView中去創(chuàng)建UIViewController的view汛兜,也就是self.view巴粪。

在這個(gè)方法中主要完成一些關(guān)鍵view的初始化工作。加載成功后接著調(diào)用viewDidLoad方法粥谬。

在loadView之前肛根,self.view是不存在的,也就是說view還沒有被初始化漏策,loadView完成后view就建立好了派哲。

比如:

- (void)loadView { 
      NSLog(@"loadView中調(diào)用self.view : %@", self.view);
}

這樣會(huì)直接崩潰,因?yàn)閟elf.view 還沒創(chuàng)建掺喻。
在重寫的loadView中調(diào)用[super loadView]芭届,會(huì)自動(dòng)初始化self.view。如下方式就不會(huì)崩潰:

- (void)loadView { 
    [super loadView]; 
    NSLog(@"loadView中調(diào)用self.view : %@", self.view);
}

2感耙、每次訪問UIViewController的view(比如vc.view喉脖、self.view)而且view為nil,loadView方法就會(huì)被調(diào)用抑月。

- (void)loadView { 
    [super loadView]; 
    NSLog(@"loadView中調(diào)用self.view : %@", self.view);
}
- (void)viewDidLoad { 
    [super viewDidLoad]; 
    self.view = nil; 
    self.view.backgroundColor = [UIColor redColor]; 
//這時(shí)候view為nil,會(huì)再次調(diào)用loadView方法舆蝴。執(zhí)行完  loadView后繼續(xù)執(zhí)行viewDidLoad方法谦絮,這樣就死循環(huán)了。
}

上面代碼 直接就死循環(huán)了洁仗,一直執(zhí)行l(wèi)oadView和viewDidLoad方法层皱。

3、loadView中自定義了view赠潦,那么xib叫胖、storyboard中設(shè)置的頁面就會(huì)失效,frame也是無效的她奥。如:

- (void)loadView { 
UIView *customView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; 
customView.backgroundColor = [UIColor redColor]; 
self.view = customView;
}

上面代碼執(zhí)行的效果是 全屏都是紅色瓮增。

4、修改self.view的大小哩俭,可以在 viewDidLayoutSubviews 方法里去修改:

- (void)viewWillLayoutSubviews {
 self.view.frame = CGRectMake(0, 0, 150, 150);
}

5绷跑、默認(rèn)的[super loadView] 中做了哪些事情:

5.1、如果UIViewController制定xib的名字或者storyboard 進(jìn)行初始化 凡资,這樣就會(huì)根據(jù)傳入的xib的名字 去初始化view砸捏。

5.2、如果xib沒有顯示的指定名稱,就默認(rèn)加載和UIViewController同名的xib文件垦藏。

5.3梆暖、如果沒有找到xib文件就會(huì)創(chuàng)建 一個(gè)空白的UIView,這個(gè)view的frame為屏幕的大小掂骏。

五轰驳、viewDidLoad

loadView執(zhí)行完成后調(diào)用viewDidLoad,viewDidLoad中主要完成界面的初始化 芭挽。如:往view上添加子視圖滑废、讀取數(shù)據(jù)等。

頁面打開后袜爪,如果沒有銷毀 就只執(zhí)行一次蠕趁。

六、viewWillAppear

viewDidLoad執(zhí)行完成后就執(zhí)行viewWillAppear辛馆。每次打開頁面都會(huì)執(zhí)行viewWillAppear俺陋。比如:從A頁面push到B頁面,然后從B頁面返回到A頁面的時(shí)候昙篙,viewDidLoad就不再執(zhí)行腊状,而viewWillAppear還是會(huì)執(zhí)行。

如果要求每次顯示該頁面的時(shí)候都要刷新網(wǎng)絡(luò)數(shù)據(jù)苔可,就可以在viewWillAppear做網(wǎng)絡(luò)請(qǐng)求的操作缴挖。

七、updateViewConstraints

主要功能是更新view的約束,并會(huì)調(diào)用其所有子視圖的該方法去更新約束焚辅。

ViewController的View在更新視圖布局時(shí)映屋,會(huì)先調(diào)用ViewController的updateViewConstraints 方法。我們可以通過重寫這個(gè)方法去更新當(dāng)前View的內(nèi)部布局同蜻,而不用再繼承這個(gè)View去重寫-updateConstraints方法棚点。

兩個(gè)方法都需要在方法實(shí)現(xiàn)的最后調(diào)用父類的該方法。并且這兩個(gè)方法不建議直接調(diào)用湾蔓。

- (void)updateViewConstraints {
    //在這里給view添加約束瘫析,請(qǐng)確保該view的translatesAutoresizingMaskIntoConstraints屬性已設(shè)置為false
    [super updateViewConstraints];
}

八、viewWillLayoutSubviews

view即將布局其Subviews默责。比如view的bounds改變了贬循,要調(diào)整Subviews的位置,在調(diào)整之前要做的一些工作就可以在該方法中實(shí)現(xiàn)桃序。

我們可以在這里設(shè)置 subviews 的 frame 屬性甘有。

在 Autolayout 機(jī)制被調(diào)用之前,viewWillLayoutSubviews 會(huì)被調(diào)用葡缰,在 Autolayout 機(jī)制被調(diào)用之后亏掀,viewDidLayoutSubviews 會(huì)被調(diào)用忱反。即在 viewWillLayoutSubviews 和 viewDidLayoutSubviews 之間,Autolayout 機(jī)制會(huì)被調(diào)用滤愕。所以從viewWillLayoutSubviews 中獲取的frame 是老的frame温算,從viewDidLayoutSubviews獲取的frame才是正確的frame。

比如xib中設(shè)置了約束间影,然后 在viewDidLoad中設(shè)置frame注竿,真實(shí)的位置還是根據(jù)xib中的約束顯示的。

而且在viewWillLayoutSubviews中修改frame也是不生效的魂贬,那么巩割,如何才能用代碼修改布局生效?

方法一:
在viewDidLayoutSubviews中修改frame付燥,這是最簡單的方法宣谈。

方法二:推薦做法

在updateConstraints中修改約束。
方法三:
在viewWillLayoutSubviews中修改約束

九键科、viewDidLayoutSubviews

控制器的view布局子控件完成闻丑。這里獲取的frame才是最正確的frame。

如果控件用的約束來布局的勋颖,在viewDidLayoutSubviews 中 去設(shè)置視圖的frame 是無效的嗦嗡。

如果控件是用frame來布局的,在viewDidLayoutSubviews 中 去設(shè)置視圖的frame 是有效的饭玲。

self.view 在viewDidLayoutSubviews 中 去設(shè)置 frame 是有效的侥祭。

十、viewWillDisappear

控制器的view即將消失的時(shí)候

十一茄厘、viewDidDisappear

控制器的view完全消失的時(shí)候

十二矮冬、 dealloc

當(dāng)對(duì)象被釋放的時(shí)候調(diào)用dealloc。

ARC中dealloc方法中常用的一些作用:

在dealloc中移除掉notification蚕断,解除delegate關(guān)系。

看一個(gè)類中是否有循環(huán)引用入挣,可以用Instrument或者FBMemoryProfiler亿乳,不過最簡單的還是在dealloc里打印日志。

十三径筏、didReceiveMemoryWarning

當(dāng)系統(tǒng)內(nèi)存不足時(shí)葛假,VC的didReceiveMemoryWarining 方法會(huì)被調(diào)用,VC所在的導(dǎo)航棧(self.navigationController.viewControllers)中的VC 也會(huì)被調(diào)didReceiveMemoryWarining滋恬。

didReceiveMemoryWarining 會(huì)判斷當(dāng)前VC的view是否顯示在window上聊训,

如果沒有顯示在window上,則didReceiveMemoryWarining 會(huì)自動(dòng)將VC 的view以及其所有子view全部銷毀恢氯。

如果當(dāng)前UIViewController的view顯示在window上带斑,則不銷毀該viewcontroller的view鼓寺。

AppStore中一些可以釋放內(nèi)存的APP,就是先不斷增加使用的內(nèi)存勋磕,然后系統(tǒng)檢測到內(nèi)存不足的時(shí)候 會(huì)自動(dòng)進(jìn)行回收妈候。

擴(kuò)展:http://www.reibang.com/p/a5f82922e387

loadView方法

當(dāng)我們用到控制器view時(shí),就會(huì)調(diào)用控制器view的get方法挂滓,在get方法內(nèi)部苦银,首先判斷view是否已經(jīng)創(chuàng)建,如果已存在赶站,則直接返回存在的view幔虏,如果不存在,則調(diào)用控制器的loadView方法贝椿,在控制器沒有被銷毀的情況下想括,loadView也可能會(huì)被執(zhí)行多次

viewDidLoad方法

當(dāng)控制器的loadView方法執(zhí)行完畢,view被創(chuàng)建成功后团秽,就會(huì)執(zhí)行viewDidLoad方法主胧,該方法與loadView方法一樣,也有可能被執(zhí)行多次习勤。在開發(fā)中踪栋,我們可能從未遇到過執(zhí)行多次的情況,那什么時(shí)候會(huì)執(zhí)行多次呢图毕?

比如A控制器push出B控制器夷都,此時(shí),窗口顯示的是B控制器的view予颤,此時(shí)如果收到內(nèi)存警告囤官,我們一般會(huì)將A控制器中沒用的變量及view銷毀掉,之后當(dāng)我們從B控制器pop到A控制器時(shí)蛤虐,就會(huì)再次執(zhí)行A控制器的loadView方法與viewDidLoad方法党饮。

控制器view的加載
1.通過storyboard加載
當(dāng)控制器通過storyboard加載時(shí),需要指定storyboard的名稱驳庭,控制器view最終就是storyboard所描述的樣子刑顺。

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{   
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"TestViewController" bundle:nil];      
    TestViewController *testVC = [storyboard instantiateInitialViewController];   
    [self.navigationController pushViewController:testVC animated:YES]; 
}

2.通過xib加載當(dāng)控制器view通過xib加載的時(shí)候,可能會(huì)出現(xiàn)三種情況

a. 指定xib名稱(OtherViewController.xib)

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{   
    TestViewController *testVC = [[TestViewController alloc] initWithNibName:@"OtherViewController" bundle:nil];   
    [self.navigationController pushViewController:testVC animated:YES]; 
}

當(dāng)我們指定了xib的名稱饲常,loadView方法就會(huì)去加載對(duì)應(yīng)的xib(OtherViewController.xib)

b.不指定xib名稱1

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{   
    TestViewController *testVC = [[TestViewController alloc] init];   
    [self.navigationController pushViewController:testVC animated:YES]; 
}

如果我們不指定xib名稱蹲堂,loadView就會(huì)加載與控制器同名的xib(TestViewController.xib)

c.不指定xib名稱2
我們先將TestViewController.xib這個(gè)文件刪除掉。
當(dāng)沒有指定xib名稱贝淤,且沒有與控制器同名的xib時(shí)柒竞,會(huì)加載前綴與控制器名相同而不帶controller的xib(TestView.xib)。

3.不通過sb\xib加載
將TestView.xib這個(gè)文件也刪除掉播聪,再來運(yùn)行程序朽基,結(jié)果是黑色的布隔。
控制器view是存在的,只不過顏色為clearColor踩晶,所以看到的黑色其實(shí)是UIWindow的执泰。

4.重寫loadView方法
我們重寫TestViewController的loadView方法,里面不做任何事

- (void)loadView { }

結(jié)果跟上面一樣黑渡蜻,不同的是术吝,這次并沒有創(chuàng)建view,最外層并不是UIView

如果我們希望控制器view加載出來的時(shí)候不是UIView而是其他控件茸苇,比如UIImageView排苍,那我們就可以重寫loadView

- (void)loadView
{   
    self.view = [[UIImageView alloc] init]; 
}

結(jié)論
1.重寫loadView方法,則會(huì)根據(jù)重寫的loadView方法創(chuàng)建view
2.控制器通過storyboard加載学密,則根據(jù)storyboard的描述創(chuàng)建view
3.控制器view通過xib加載淘衙,則根據(jù)nibName對(duì)應(yīng)的xib創(chuàng)建view
4.沒有指定nibName,則根據(jù)與控制器同名的xib創(chuàng)建view
5.沒有同名的xib腻暮,則根據(jù)與控制器名前綴相同不帶controller的xib創(chuàng)建view
6.如果都沒有彤守,則創(chuàng)建一個(gè)空白的xib
7.awakeFromNib當(dāng)控制器從nib加載的時(shí)候就會(huì)調(diào)用這個(gè)方法
8.storyboard加載的是控制器及控制器view,而xib加載的僅僅只是控制器的view

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末哭靖,一起剝皮案震驚了整個(gè)濱河市具垫,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌试幽,老刑警劉巖筝蚕,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異铺坞,居然都是意外死亡起宽,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門济榨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來坯沪,“玉大人,你說我怎么就攤上這事擒滑「溃” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵橘忱,是天一觀的道長赴魁。 經(jīng)常有香客問我卸奉,道長钝诚,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任榄棵,我火速辦了婚禮凝颇,結(jié)果婚禮上潘拱,老公的妹妹穿的比我還像新娘。我一直安慰自己拧略,他們只是感情好芦岂,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著垫蛆,像睡著了一般禽最。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上袱饭,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天川无,我揣著相機(jī)與錄音,去河邊找鬼虑乖。 笑死懦趋,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的疹味。 我是一名探鬼主播仅叫,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼糙捺!你這毒婦竟也來了诫咱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤继找,失蹤者是張志新(化名)和其女友劉穎遂跟,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體婴渡,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡幻锁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了边臼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片哄尔。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖柠并,靈堂內(nèi)的尸體忽然破棺而出岭接,到底是詐尸還是另有隱情,我是刑警寧澤臼予,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布鸣戴,位于F島的核電站,受9級(jí)特大地震影響粘拾,放射性物質(zhì)發(fā)生泄漏窄锅。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一缰雇、第九天 我趴在偏房一處隱蔽的房頂上張望入偷。 院中可真熱鬧追驴,春花似錦、人聲如沸疏之。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锋爪。三九已至丙曙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間其骄,已是汗流浹背河泳。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留年栓,地道東北人拆挥。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像某抓,于是被迫代替她去往敵國和親纸兔。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 7否副、不使用IB是汉矿,下面這樣做有什么問題笛质? 6事扭、請(qǐng)說說Layer和View的關(guān)系,以及你是如何使用它們的绅项。 1.首先...
    AlanGe閱讀 674評(píng)論 0 1
  • 1.xcode5和xcode7區(qū)別 1.xcode7沒有Frameworks文件夾,xcode7內(nèi)部會(huì)自動(dòng)幫你導(dǎo)入...
    彼岸的黑色曼陀羅閱讀 515評(píng)論 0 2
  • 一曲尸、PCH 文件PCH 是一個(gè)頭文件赋续,能被項(xiàng)目中的所有源文件共享和訪問。 PCH 文件的需求一個(gè)宏或者頭文件等另患,很...
    iChuck閱讀 316評(píng)論 0 0
  • 最近看了一下java中多線程并發(fā)同步問題纽乱。 一、對(duì)于開發(fā)中做鍵值對(duì)的操作我們常用的Map來存儲(chǔ)對(duì)應(yīng)信息昆箕。 Map ...
    設(shè)計(jì)獅家的非典型程序員閱讀 289評(píng)論 0 0
  • 95后已經(jīng)正式步入工作了鹏倘!這說明什么薯嗤? 人們口中那群好吃懶做、充滿個(gè)性的90后已經(jīng)大部分開始工作纤泵、結(jié)婚生子骆姐、甚至有...
    夢翊少女閱讀 482評(píng)論 3 3