一:項(xiàng)目中的常見文件
1.Tests文件夾:單元測(cè)試
2.Frameworks:依賴的框架
3.Info.plist: 項(xiàng)目配置文件.程序加載首先加載配置文件.
3.1 Localiztion native development region(CFBundleDevelopmentRegion) 本地化相關(guān)
3.2 Bundle display name(CFBundleDisplayName) 程序安裝后顯示的名稱,限制在10-12個(gè)字符
3.3 Icon file(CFBundleIconFile) app圖標(biāo)名稱,一般為Icon.png
3.4 Bundle version(CFBundleShortVersionString) 應(yīng)用程序版本號(hào),每次發(fā)布appstore時(shí)需要增加這個(gè)版本號(hào)
3.5 Main storyboard file base name(NSMainStoryboardFile) 主storyboard文件的名稱
3.6 Bundle identifier(CFBundleIdentifier) 項(xiàng)目唯一標(biāo)識(shí),部署真機(jī)時(shí)使用
4.Info.plist對(duì)應(yīng)xcode的圖形界面,改變圖形界面,就會(huì)改變Info.plist.
5.pch文件: Supporting files文件夾下"工程名-Prefix.pch"的文件,是一個(gè)頭文件,能被項(xiàng)目中的其他所有源文件共享和訪問.
5.1 pch文件的作用
1.放一些全局的宏.
2.導(dǎo)入一些全局都需要的頭文件.
3.管理日志輸出
日志輸出是非常消耗性能的,發(fā)版時(shí)候不需要日志輸出,只有debug才需要.
5.2 自定義輸出,不要使用系統(tǒng)自帶的NSLog
define NQQLog(...) NSLog(VA_ARGS)
//標(biāo)識(shí)可接受任何參數(shù)
VA_ARGS 標(biāo)識(shí)左邊...的參數(shù)會(huì)替代到右邊NSLog中.
1.如果不想打印了,直接注釋后面的 #define NQQLog(...) // NSLog(VA_ARGS)
2.還可以使用條件編譯
#ifdef DEBUG //調(diào)試階段
#define NQQLog(...) NSLog(VA__ARGS)
#else //發(fā)版階段
#define NQQLog(...)
#endif
5.3 在pch寫的有關(guān)oc代碼,最好放在#define OBJC , xcode在每個(gè)oc文件中都定義了這個(gè)宏,只有oc文件才有這些宏.
二.UIApplication
1.UIApplication不能手動(dòng)創(chuàng)建,一個(gè)app只允許有一個(gè).
每一個(gè)app都有自己的UIApplication對(duì)象,并且是單例的.
[UIApplication sharedApplication]可以獲得這個(gè)單例對(duì)象
一個(gè)app啟動(dòng)后創(chuàng)建的第一個(gè)對(duì)象就是UIApplication對(duì)象.
2.UIApplication的作用: 做應(yīng)用級(jí)別的操作
2.1 app紅色提醒數(shù)字
@property(nonatomic) NSInteger applicationIconBadgeNumber;
2.2 顯示聯(lián)網(wǎng)狀態(tài)可見性
@property(nonatomic,getter=isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible;
2.3 打開一個(gè)資源
3.openURL:
//UIApplication有個(gè)功能強(qiáng)大的openURL方法
- (BOOL)openURL:(NSURL *)url;
//打電話
UIApplication *app = [UIApplication sharedApplication];
[app openURL:[NSURL URLWithString:@"tel://10086"];
//發(fā)短信
[app openURL:[NSURL URLWithString:@"sms://10086"];
//發(fā)郵件
[app openURL:[NSURL URLWithString:@"mailto://328477273@qq.com"];
//打開一個(gè)網(wǎng)頁資源
[app openURL:[NSURL URLWithString:@"http://www.itdecent.cn"];
4.UIApplication打開資源的好處:不用判斷用什么軟件打開的,系統(tǒng)會(huì)根據(jù)協(xié)議頭判斷.
5.UIApplication管理狀態(tài)欄, iOS7后提供了2種管理狀態(tài)欄的方式
5.1 通過UIViewController管理(每一個(gè)UIViewController都可以擁有自己不同的狀態(tài)欄).
5.2 通過UIApplication管理(一個(gè)應(yīng)用程序狀態(tài)欄都由它同一個(gè)管理)
//如果想利用UIApplication管理狀態(tài)欄,首先要修改Info.plist

5.3 iOS7,默認(rèn)下,狀態(tài)欄都是由UIViewController管理的
//狀態(tài)欄樣式
- (UIStatusBarStyle)preferredStatusBarStyle;
//狀態(tài)欄的可見性
- (BOOL)prefersStatusBarHidden;
三.UIApplication 和 delegate
- 所有的移動(dòng)操作系統(tǒng)都有一個(gè)致命的缺點(diǎn),app容易受到打擾.比如來電或者鎖屏?xí)?dǎo)致app進(jìn)入后臺(tái)甚至被終止.
在app收到干擾時(shí),會(huì)產(chǎn)生一些系統(tǒng)事件,此時(shí)UIApplication會(huì)通知它的delegate對(duì)象,讓delegate代理對(duì)象來處理這些系統(tǒng)事件.
AppDelegate就是UIApplication的代理.
AppDelegate默認(rèn)遵守了UIApplicationDelegate協(xié)議.

- app啟動(dòng)過程:
2.1 創(chuàng)建application, 創(chuàng)建并設(shè)置application的代理.
2.2 開啟事件循環(huán),不斷監(jiān)聽事件.如果產(chǎn)生系統(tǒng)事件,就會(huì)通知代理,其他事件,會(huì)找到一個(gè)合適的視圖處理事件.
2.3 只有應(yīng)用程序關(guān)閉,才會(huì)結(jié)束程序.
UIApplicationMain函數(shù)會(huì)開啟一個(gè)事件循環(huán),并不會(huì)馬上就執(zhí)行完畢.
底層機(jī)制:
創(chuàng)建UIApplication對(duì)象和UIApplicationDelegate對(duì)象,設(shè)置UIApplication的代理,開啟事件循環(huán),監(jiān)聽系統(tǒng)事件.
2.4 delegateClassName不能傳nil,意味著application沒有代理,就無法監(jiān)聽系統(tǒng)的事件,系統(tǒng)的事件都沒法監(jiān)聽,窗口都不知道什么時(shí)候去加載, 由于視圖都是懶加載的,因此就不會(huì)創(chuàng)建窗口,什么也沒有.
2.5 principalClassName傳nil,默認(rèn)是UIApplication,創(chuàng)建一個(gè)UIApplication對(duì)象.
2.6 UIApplication代理的作用: 處理系統(tǒng)事件,不是任何事件都交給它處理, 按鈕點(diǎn)擊,屏幕點(diǎn)擊都不是它處理, 是由UIApplication處理.
2.6.1 加載完成,初始化操作
2.6.2 進(jìn)入后臺(tái): 一般在這里保存應(yīng)用的數(shù)據(jù)(游戲數(shù)據(jù),暫停游戲)
2.6.3 內(nèi)存警告: 清空不必要的內(nèi)容.
四.UIWindow
一種特殊的UIView,通常一個(gè)app中至少會(huì)有一個(gè)UIWindow.
app啟動(dòng)后,創(chuàng)建的第一個(gè)視圖控件就是UIWindow,接著創(chuàng)建控制器的View,最后將控制器的View添加到UIWindow上.沒有UIWindow就看不見任何東西.
1.添加UIView到UIWindow
//直接將view添加到UIWindow中,但并不會(huì)理會(huì)view對(duì)應(yīng)的UIViewController
- (void)addSubView:(UIView *)view;
//自動(dòng)將rootViewController的view添加到UIWindow中,管理rootViewController的生命周期.
@propery(nonatomic,retain) UIViewController *rootViewController;
//讓當(dāng)前UIWindow變成keyWindow
- (void)makeKeyWindow;
//讓當(dāng)前UIWindow變成keyWindow,并顯示出來
-(void)makeKeyAndVisible;
- UIWindow的獲得
2.1 [UIApplication sharedApplication].windows
//用來接收鍵盤一集非觸摸類的消息事件的UIWindow,而且程序中每個(gè)時(shí)刻只能有一個(gè)UIWindow是keyWindow.如果某個(gè)UIWindow內(nèi)部的文本框不能輸入文字,可能是因?yàn)檫@個(gè)UIWindow不是keyWindow.
2.2 [UIApplication sharedApplication].keyWindow
//獲得某個(gè)UIView所在的UIWindow
view.window

關(guān)于UIWindow的一些補(bǔ)充:
window層級(jí): UIWindowLevelNormal < UIWindowLevelStatusBar < UIWindowLevelAlert
UIWindowLevelNormal : 默認(rèn)窗口的層級(jí).
UIWindowLevelStatusBar : 狀態(tài)欄,鍵盤.
UIWindowLevelAlert : UIActionSheet,UIAlertView
把window的層級(jí)設(shè)置為UIWindowLevelAlert,就會(huì)顯示在最前面.
五.控制器的創(chuàng)建
1.怎么自己通過storyboard創(chuàng)建控制器(空項(xiàng)目),之前都是系統(tǒng)加載 storyboard,幫我們創(chuàng)建好控制器。
? 了解UIStoryboard對(duì)象,通過這個(gè)對(duì)象,就能加載storyboard文件 注意:必須要有storyboard,創(chuàng)建UIStoryboard對(duì)象才有意義,alloc init創(chuàng) 建UIStoryboard對(duì)象沒有意義
1.1> instantiateInitialViewController:默認(rèn)加載箭頭指向的控制器
1.2> instantiateViewControllerWithIdentifier:根據(jù)標(biāo)識(shí)在storyboard查找 控制器,并且創(chuàng)建。
○ 標(biāo)識(shí)不能亂傳,會(huì)報(bào)錯(cuò)的,必須storyboard有這個(gè)標(biāo)識(shí)才行。
1.3> 現(xiàn)在創(chuàng)建的控制器都不能處理事件,如果需要處理事件,需要自定 義控制器。
? 現(xiàn)在創(chuàng)建的控制器為什么不能處理事件?
? 原因:當(dāng)通過storyboardID找到storyboard中的控制器的時(shí)候,就會(huì)
創(chuàng)建storyboard中描述的控制器對(duì)象,創(chuàng)建對(duì)象首先得知道類名, 會(huì)根據(jù)storyboard中的Custom Class確定類名,然后創(chuàng)建對(duì)象,默認(rèn) 都是系統(tǒng)自帶的對(duì)控制器對(duì)象,系統(tǒng)自帶的是不能處理事件的。他 不能寫監(jiān)聽方法。
?
記住:要想處理控制器事件,必須自定義控制器。
2.模仿系統(tǒng)怎么通過main.storyboard加載程序的。(帶storyboard的項(xiàng)目) 1> 帶有storyboard的程序,默認(rèn)程序一啟動(dòng),就會(huì)加載storyboard,自動(dòng) 創(chuàng)建好窗口和根控制器。
2> 系統(tǒng)怎么判斷需不需加載storyboard?主要看有沒有設(shè)置主界面,如果 設(shè)置了Main,就會(huì)去加載Main.storyboard.
?
3> 在新增一個(gè)storyboard文件,怎么加載新增的storyboard,修改主界 面。
4> 模仿程序一啟動(dòng)就加載Main.storyboard文件,創(chuàng)建窗口,創(chuàng)建箭頭指
向的窗口根控制器,并且顯示窗口。
? 先清空主界面設(shè)置,需要?jiǎng)h除緩存。
3> storyboard storyboard
面。
4> 模仿程序一啟動(dòng)就加載Main.storyboard文件,創(chuàng)建窗口,創(chuàng)建箭頭指
向的窗口根控制器,并且顯示窗口。
? 先清空主界面設(shè)置,需要?jiǎng)h除緩存。

- 通過xib創(chuàng)建控制器的view(空項(xiàng)目) ? 首先得要有xib。
3.1 xib注意點(diǎn):(演示沒有的后果)
1> xib里面必須有一個(gè)view描述控制器的view,因?yàn)榭刂破鞯膙iew 屬性必須有值。
2> xib需要指定描述哪一個(gè)控制器,描述UIView不需要,因?yàn)閤ib里 面可以描述很多UIView,不能固定死,但是控制器就不一樣了,一個(gè) xib就用來描述一個(gè)控制器。
3> xib里面可能有很多view,需要拖線指明哪個(gè)是控制器的view
3.2 xib和storyboard的區(qū)別 storyboard已經(jīng)指定了控制器的view,不需要我們管,xib需要我們 手動(dòng)管理。
六.控制器view的創(chuàng)建
1.控制器view的加載,首先要自定義控制器view,作為根控制器.
2.直接通過alloc init創(chuàng)建的控制器的view默認(rèn)就是透明的.
3.重寫控制器的loadView,不會(huì)去加載storyboard.
4.解釋loadView方法
4.1 loadView作用: 用來創(chuàng)建自定義view
4.2 loadView調(diào)用時(shí)機(jī): 當(dāng)控制器view沒有創(chuàng)建時(shí),就會(huì)調(diào)用loadView創(chuàng)建控制器的view.
4.3 loadView使用注意: 如果重寫loadView里面沒有創(chuàng)建控制器的view,就不能使用self.view, 會(huì)造成死循環(huán).

5.通過xib加載控制器的view
NQQViewControllerAAA的xib描述控制器的view,通過這個(gè)xib加載控制器的view
NQQViewController的xib描述控制器的view,不用告訴控制器去加載哪個(gè)xib,會(huì)自動(dòng)去加載NQQViewController這個(gè)xib.
NQQView的xib描述控制器的view,通過這個(gè)xib加載控制器的view,不用告訴控制器去加載哪個(gè)xib,優(yōu)先去加載NQQView這個(gè)xib
6.控制器View的優(yōu)先級(jí):
重寫loadView > storyboard > nibName > xib
7.控制器的view是延遲加載的