iOS 基礎01—項目檔案、applecation、啟動過程、VC生命周期
1 項目中常見的檔案
-
1 info.plist 檔案
plist檔案是一個全局配置檔案,系統預設就叫做info.plist,是以如果自己取名字千萬不可以取作info.plist;
代碼裡拿到info.plist裡的參數使用
[[NSBundle mainBundle]infoDictionary]; //這個字典拿到的就是info.plist裡的東西,比如擷取版本号
NSString * versionStr = [[[NSBundle mainBundle]infoDictionary] objectForKey:@"CFBundleShortVersionString"];
另一個需要注意的是info.plist裡的Bundle name就是我們手機桌面上顯示的app名字,系統預設的是取product name
-
2 .pch 檔案
這是一個全局配置檔案,是需要自己手動建立的。在建立new file的最下面的other下有一個 pch file。生成完成之後,同樣需要自己配置一下。在build setting 裡搜 prefix header,把剛才自己建立的檔案名的路徑拖進去。
-
3 OC宏
這裡說的宏就是大概要用在PCH檔案裡面的使用到,自己以前沒見過的:
#ifdef __OBJC__ //OC檔案中使用
#ifdef DEBUG //在debug條件下執行
#define FCFLog(...) NSLog(__VA_ARGS__) //自定義的列印函數
#else
#define FCFLog(...) //NSLog(__VA_ARGS__)
#endif
#endif
- 4 這裡順帶提一下蘋果沙盒檔案裡的檔案目錄
Documents、Library、tmp這三個檔案夾。
1 Documents:蘋果建議将程式中浏覽到的資料儲存到該目錄下,對使用者可見。這個目錄用于存儲使用者資料或其他應該定期備份的資訊
2 Library:這個檔案夾下有兩個主要的子檔案夾Caches和Preferences。Preferences檔案放的就是平時我們用NSUserDefaults存取的東西;Caches則主要存取我們自己下載下傳的一些檔案資料。Library對使用者不可見。
3 tmp:是一個零時檔案夾。儲存app啟動過程中産生的資訊。
Documents和Library檔案夾在iCloud和iTunes備份的時候會被備份。tmp在iPhone重新開機或app記憶體不夠的時候就會被清空。
2 UIApplication
UIApplication 是應用程式啟動之後建立的第一個對象,且是單例對象。
大部分應用級别的設定都可以使用UIApplication進行設定
- 1 設定應用程式圖示上的未讀通知數
UIApplication * app = [UIApplication shareApplication];
UIUserNotificationSettings * setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil];
[app registerUserNotificationSettings:settings];
app.applicationIconBadgeNumber = 99;
- 2 設定應用程式狀态欄中正在請求網絡的旋轉小标志
UIApplication * app = [UIApplication shareApplication];
app.networkActivityIndicatorVIsible = YES;
- 3 跳轉URL或app或打電話
//網址
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已經進入背景——一般用來儲存資料
4、applicationWillEnterForeground //進入前台
5、applicationDidBecomeActive //擁有焦點,恢複互動能力
6、applicationWillTerminate //app銷毀的時候調用
app啟動會調用: 1——5
app進入背景依次調用: 2——3
app進入前台依次調用: 4——5
app殺死依次調用: 2——3——6
3 App啟動過程和原理
main函數之前:
作業系統iOS一開機就開始啟動一個系統的Runloop函數,以每秒60次的幀率不斷監聽這手機界面的使用者互動事件。一旦觸摸就會觸發一個觸摸事件,然後将事件放入事件隊列,緊接着就會通過端口找到對應的app,然後調用app的main函數——也就是OC檔案中的main.m檔案中的main函數
main函數:
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
main函數裡調用了UIApplicationMain函數。UIApplicationMain的第三個參數要麼是UIApplication,要麼是UIApplication的子類,第四個參數則是确定UIApplication的代理是誰。
UIApplicationMain
UIApplicationMain函數則建立UIApplication對象,設定UIApplicationMainDelegate代理
接着,開啟事件循環(消息循環) 開啟Runloop --> 加載info.plist -->如果設定了MainInterface,就加載對應的storyboard(建立window 建立初始化控制器)
4 Window
程式啟動過後建立的第一個視圖控件就是UIWindow,預設就是全屏的;
如果沒有在info.plist裡設定mian interface,那麼就得我們自己在app啟動之後(didFinishLaunchingWithOptions中)自己去建立一個window;
如果要讓window顯示則必須滿足兩個條件:
- 1、給window設定rootViewcontroller;
- 2、調用makekeyandvisible讓其可見:
_window = [[UIWindow alloc] init]; //預設的
_window.backgroundColor = [UIColorredColor];
_window.rootViewController = [[UIViewControlleralloc] init];
[_window makeKeyAndVisible];
程式會有多個window,但是隻有一個keywindow。而且是最後執行makeKeyAndVisible的window才是主視窗,注意這個和window的frame是沒有關系的:
建立第一個window
_window = [[UIWindow alloc] init]; //預設的
_window.backgroundColor = [UIColor redColor];
_window.rootViewController = [[UIViewController alloc] init];
[_window makeKeyAndVisible];
建立第二個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的各種建立方式
- 1、[alloc init]純代碼建立控制器,預設的frame就是全屏的,而且是透明色
FCFViewController * FCFVC = [[FCFViewController alloc]init];
- 2、第二種方法,通過storyboard加載
UIStoryboard * sb = [UIStoryboard storyboardWithName:@"Test" bundle:nil];
01
FCFViewController * FCFVC = [sb instantiateInitialViewController]; //這個函數傳回storyboard中initial(也就是箭頭所指的view controller,這裡需要自己去storyboad中把那個Is Initial View Controller勾上)的view controller
02
FCFViewController * FCFVC = [sb instantiateViewControllerWithIdentifier:@"switch"];
//這個函數就是根據storyboard裡view controller的對應的Storyboard id辨別符拿到的view controller
- 3、第三種方式,通過xib加載,這裡是建立View Controller不勾選建立xib,單獨建立一個xib
/* 建立一個xib,不要修改xib裡的任何東西
*File's Owner :所有者,改成view controller的類名
* 連線view :将xib的view作為所有者VC的view
*/
FCFViewController * FCFVC = [[FCFViewController alloc] initWithNibName:@"Text" bundle:nil]; //這裡傳回的是控制器vc
6 View
- 1、 純代碼 ,建立一個透明色,且frame和螢幕一樣大的view
TestViewController * vc = [[TestViewController alloc]init];
- 2、sb建立,就是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 建立同名xib,就是在單獨建立xib的時候把xib的名稱寫成VC的名稱,同樣正常配置File’s owner 和 連線view, alloc init就可以了,系統會找同名的xib-“TestViewController”,如果沒有就加載同名的不帶Controller的xib-“TestView”.
TestViewController * vc = [[TestViewController alloc]init]; //先找TestViewController,再找TestView
7、ViewController生命周期
-
1、這裡最關鍵的兩點就是loadView的執行時機和viewDidLoad的執行時機。
loadView是懶加載,如果我們沒有在init方法是使用self.view,正常的加載順序就是init執行完之後——>執行loadview——>執行viewDidLoad。但是因為loadView是懶加載,是以在init方法裡面調用了self.view,那麼在用到self.view的時候就會馬上執行loadView,執行完loadView馬上會執行viewDidLoad,然後才傳回init方法裡執行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");
}
這裡執行的結果是:1、3、4、5、7、2。注意這裡不會執行6,因為那時還沒執行self.boolvalue=YES,而BOOL的預設值是false。
如果這裡把self.view.backgroundColor = [UIColor redColor];注釋掉,則執行的結果就是:1、2、3、4、5、6、7
可以去github上檢視Demo,喜歡的話star一下哦
github
CSDN