iOS 基礎01--項目文件、applecation称勋、啟動過程胸哥、VC生命周期
1 項目中常見的文件
- 1 info.plist 文件
plist文件是一個全局配置文件,系統(tǒng)默認就叫做info.plist赡鲜,所以如果自己取名字千萬不可以取作info.plist烘嘱;
代碼里拿到info.plist里的參數(shù)使用
[[NSBundle mainBundle]infoDictionary]; //這個字典拿到的就是info.plist里的東西,比如獲取版本號
NSString * versionStr = [[[NSBundle mainBundle]infoDictionary] objectForKey:@"CFBundleShortVersionString"];
另一個需要注意的是info.plist里的Bundle name就是我們手機桌面上顯示的app名字,系統(tǒng)默認的是取product name
2 .pch 文件
這是一個全局配置文件蝗蛙,是需要自己手動創(chuàng)建的蝇庭。在創(chuàng)建new file的最下面的other下有一個 pch file。生成完成之后捡硅,同樣需要自己配置一下哮内。在build setting 里搜 prefix header,把剛才自己新建的文件名的路徑拖進去壮韭。3 OC宏
這里說的宏就是大概要用在PCH文件里面的使用到北发,自己以前沒見過的:
#ifdef __OBJC__ //OC文件中使用
#ifdef DEBUG //在debug條件下執(zhí)行
#define FCFLog(...) NSLog(__VA_ARGS__) //自定義的打印函數(shù)
#else
#define FCFLog(...) //NSLog(__VA_ARGS__)
#endif
#endif
- 4 這里順帶提一下蘋果沙盒文件里的文件目錄
Documents、Library喷屋、tmp這三個文件夾琳拨。
1 Documents:蘋果建議將程序中瀏覽到的數(shù)據(jù)保存到該目錄下,對用戶可見屯曹。這個目錄用于存儲用戶數(shù)據(jù)或其他應該定期備份的信息
2 Library:這個文件夾下有兩個主要的子文件夾Caches和Preferences狱庇。Preferences文件放的就是平時我們用NSUserDefaults存取的東西;Caches則主要存取我們自己下載的一些文件數(shù)據(jù)恶耽。Library對用戶不可見密任。
3 tmp:是一個零時文件夾。保存app啟動過程中產(chǎn)生的信息偷俭。
Documents和Library文件夾在iCloud和iTunes備份的時候會被備份浪讳。tmp在iPhone重啟或app內存不夠的時候就會被清空。
2 UIApplication
UIApplication 是應用程序啟動之后創(chuàng)建的第一個對象涌萤,且是單例對象淹遵。
大部分應用級別的設置都可以使用UIApplication進行設置
- 1 設置應用程序圖標上的未讀通知數(shù)
UIApplication * app = [UIApplication shareApplication];
UIUserNotificationSettings * setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil];
[app registerUserNotificationSettings:settings];
app.applicationIconBadgeNumber = 99;
- 2 設置應用程序狀態(tài)欄中正在請求網(wǎng)絡的旋轉小標志
UIApplication * app = [UIApplication shareApplication];
app.networkActivityIndicatorVIsible = YES;
- 3 跳轉URL或app或打電話
//網(wǎng)址
UIApplication * app = [UIApplication shareApplication];
[app openURL:[NSURL URLWithString:@"https://www.baidu.com"] options:[[NSDictionary alloc] init] completionHandler:^(BOOL success) {
}];
//電話
[app openURL:[NSURL URLWithString:@"tel://10086"] options:[[NSDictionary alloc] init] completionHandler:^(BOOL success) {
}];
- 4 AppDelegate 生命周期
1口猜、didFinishLaunchingWithOptions //app啟動完畢
2、applicationWillResignActive //失去焦點:失去和用戶的交互能力
3透揣、applicationDidEnterBackground //app已經(jīng)進入后臺——一般用來保存數(shù)據(jù)
4济炎、applicationWillEnterForeground //進入前臺
5、applicationDidBecomeActive //擁有焦點淌实,恢復交互能力
6、applicationWillTerminate //app銷毀的時候調用
app啟動會調用: 1——5
app進入后臺依次調用: 2——3
app進入前臺依次調用: 4——5
app殺死依次調用: 2——3——6
3 App啟動過程和原理
main函數(shù)之前:
操作系統(tǒng)iOS一開機就開始啟動一個系統(tǒng)的Runloop函數(shù)猖腕,以每秒60次的幀率不斷監(jiān)聽這手機界面的用戶交互事件拆祈。一旦觸摸就會觸發(fā)一個觸摸事件,然后將事件放入事件隊列倘感,緊接著就會通過端口找到對應的app放坏,然后調用app的main函數(shù)——也就是OC文件中的main.m文件中的main函數(shù)
main函數(shù):
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
main函數(shù)里調用了UIApplicationMain函數(shù)。UIApplicationMain的第三個參數(shù)要么是UIApplication老玛,要么是UIApplication的子類淤年,第四個參數(shù)則是確定UIApplication的代理是誰。
UIApplicationMain
UIApplicationMain函數(shù)則創(chuàng)建UIApplication對象蜡豹,設置UIApplicationMainDelegate代理
接著麸粮,開啟事件循環(huán)(消息循環(huán)) 開啟Runloop --> 加載info.plist -->如果設置了MainInterface,就加載對應的storyboard(創(chuàng)建window 創(chuàng)建初始化控制器)
4 Window
程序啟動過后創(chuàng)建的第一個視圖控件就是UIWindow镜廉,默認就是全屏的弄诲;
如果沒有在info.plist里設置mian interface,那么就得我們自己在app啟動之后(didFinishLaunchingWithOptions中)自己去創(chuàng)建一個window娇唯;
如果要讓window顯示則必須滿足兩個條件:
- 1齐遵、給window設置rootViewcontroller;
- 2塔插、調用makekeyandvisible讓其可見:
_window = [[UIWindow alloc] init]; //默認的
_window.backgroundColor = [UIColorredColor];
_window.rootViewController = [[UIViewControlleralloc] init];
[_window makeKeyAndVisible];
程序會有多個window梗摇,但是只有一個keywindow。而且是最后執(zhí)行makeKeyAndVisible的window才是主窗口想许,注意這個和window的frame是沒有關系的:
創(chuàng)建第一個window
_window = [[UIWindow alloc] init]; //默認的
_window.backgroundColor = [UIColor redColor];
_window.rootViewController = [[UIViewController alloc] init];
[_window makeKeyAndVisible];
創(chuàng)建第二個window
_window1 = [[UIWindow alloc] init]; //默認的
_window1.backgroundColor = [UIColor blueColor];
_window1.frame = CGRectMake(20, 20, 100, 200);
_window1.rootViewController = [[UIViewController alloc] init];
[_window1 makeKeyAndVisible];
在keywindow上加一個view
UIView * test = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
test.backgroundColor = [UIColor yellowColor];
[[UIApplication sharedApplication].keyWindow addSubview:test];
說明keywindow是window1
window有三個層級:UIWindowLevelNormal伶授、UIWindowLevelAlert、UIWindowLevelStatusBar
如果沒有設置level流纹,則window就是按照makeKeyAndVisible的調用順序依次添加進去的谎砾。如果設置了層級,則層級從最底層到最上層依次是UIWindowLevelNormal——UIWindowLevelStatusBar——UIWindowLevelAlert
5 ViewController
UIViewController的各種創(chuàng)建方式
- 1捧颅、[alloc init]純代碼創(chuàng)建控制器景图,默認的frame就是全屏的,而且是透明色
FCFViewController * FCFVC = [[FCFViewController alloc]init];
- 2碉哑、第二種方法挚币,通過storyboard加載
UIStoryboard * sb = [UIStoryboard storyboardWithName:@"Test" bundle:nil];
01
FCFViewController * FCFVC = [sb instantiateInitialViewController]; //這個函數(shù)返回storyboard中initial(也就是箭頭所指的view controller亮蒋,這里需要自己去storyboad中把那個Is Initial View Controller勾上)的view controller
02
FCFViewController * FCFVC = [sb instantiateViewControllerWithIdentifier:@"switch"];
//這個函數(shù)就是根據(jù)storyboard里view controller的對應的Storyboard id標識符拿到的view controller
- 3、第三種方式妆毕,通過xib加載慎玖,這里是創(chuàng)建View Controller不勾選創(chuàng)建xib,單獨創(chuàng)建一個xib
/* 創(chuàng)建一個xib笛粘,不要修改xib里的任何東西
*File's Owner :所有者趁怔,改成view controller的類名
* 連線view :將xib的view作為所有者VC的view
*/
FCFViewController * FCFVC = [[FCFViewController alloc] initWithNibName:@"Text" bundle:nil]; //這里返回的是控制器vc
6 View
- 1、 純代碼 ,創(chuàng)建一個透明色薪前,且frame和屏幕一樣大的view
TestViewController * vc = [[TestViewController alloc]init];
- 2润努、sb創(chuàng)建,就是storyboard里面的view
TestViewController * vc = [[UIStoryboard storyboardWithName:@"Test" bundle:nil] instantiateInitialViewController];
- 3、xib 指定xib,view就是xib里描述的一樣
TestViewController * vc = [[TestViewController alloc] initWithNibName:@"View" bundle:nil];
- 4示括、xib 創(chuàng)建同名xib,就是在單獨創(chuàng)建xib的時候把xib的名稱寫成VC的名稱铺浇,同樣正常配置File's owner 和 連線view, alloc init就可以了,系統(tǒng)會找同名的xib-"TestViewController",如果沒有就加載同名的不帶Controller的xib-"TestView".
TestViewController * vc = [[TestViewController alloc]init]; //先找TestViewController,再找TestView
7垛膝、ViewController生命周期
- 1鳍侣、這里最關鍵的兩點就是loadView的執(zhí)行時機和viewDidLoad的執(zhí)行時機。
loadView是懶加載吼拥,如果我們沒有在init方法是使用self.view倚聚,正常的加載順序就是init執(zhí)行完之后——>執(zhí)行l(wèi)oadview——>執(zhí)行viewDidLoad。但是因為loadView是懶加載凿可,所以在init方法里面調用了self.view秉沼,那么在用到self.view的時候就會馬上執(zhí)行l(wèi)oadView,執(zhí)行完loadView馬上會執(zhí)行viewDidLoad矿酵,然后才返回init方法里執(zhí)行self.view之后的代碼唬复,實例:
@interface TestController ()
@property (nonatomic, assign)BOOL boolvalue;
@end
@implementation TestController
- (instancetype)init
{
self = [super init];
if (self) {
NSLog(@"1");
self.view.backgroundColor = [UIColor redColor];
self.boolvalue = YES;
NSLog(@"2");
}
return self;
}
- (void)loadView{
NSLog(@"3");
self.view = [UIView new];
NSLog(@"4");
}
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"5");
if (self.boolvalue) {
NSLog(@"6");
}
NSLog(@"7");
}
這里執(zhí)行的結果是:1、3全肮、4敞咧、5、7辜腺、2休建。注意這里不會執(zhí)行6,因為那時還沒執(zhí)行self.boolvalue=YES评疗,而BOOL的默認值是false测砂。
如果這里把self.view.backgroundColor = [UIColor redColor];注釋掉,則執(zhí)行的結果就是:1百匆、2砌些、3、4、5存璃、6仑荐、7