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
网友评论