一、Info.plist常见的设置


1、建立一个工程后,会在Supporting files文件夹下看到一个“工程名-Info.plist”的文件,该文件对工程做一些运行期的配置,非常重要,不能删除

在旧版本Xcode创建的工程中,这个配置文件的名字就叫“Info.plist”

项目中其他Plist文件不能带有“Info”这个字眼,不然会被错认为是传说中非常重要的“Info.plist”

项目中还有一个InfoPlist.strings的文件,跟Info.plist文件的本地化相关

2、常见属性(红色部分是用文本编辑器打开时看到的key)
Localiztion native development region(CFBundleDevelopmentRegion)-本地化相关

Bundle display name(CFBundleDisplayName)-程序安装后显示的名称,限制在10-12个字符,如果超出,将被显示缩写名称

Icon file(CFBundleIconFile)-app图标名称,一般为Icon.png

Bundle version(CFBundleVersion)-应用程序的版本号,每次往App Store上发布一个新版本时,需要增加这个版本号

Main storyboard file base name(NSMainStoryboardFile)-主storyboard文件的名称

Bundle identifier(CFBundleIdentifier)-项目的唯一标识,部署到真机时用到

3、PCH文件

pch也是一个头文件,提前编译
Build Setting -> prefix
pch作用:

1.存放一些公用的宏
2.存放一些公用的头文件
3.自定义Log

pch原理:就是把pch文件中的内容拷贝到所有文件的头部

注意点:
pch文件一定要注意做些判断,判断下是否是OC文件,如果是就导入OC的代码

.pch

// 应该在OC文件中导入以下宏
// 所有的OC文件都会定义__OBJC__这个宏,苹果定义
#ifdef __OBJC__
// 获取当前手机系统的版本
#define iOS8 ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) #import "UIImage+Image.h" // 自定义Log
// ...表示宏里面的可变参数
// __VA_ARGS__表示函数里面的可变参数 #ifdef DEBUG // 表示当前调试阶段 #define XMGLog(...) NSLog(__VA_ARGS__) #else // 发布阶段 #define XMGLog(...) #endif #endif

二、UIApplication


1、什么是UIApplication
UIApplication对象是应用程序的象征

每一个应用都有自己的UIApplication对象,而且是单例的

通过[UIApplication sharedApplication]可以获得这个单例对象

一个iOS程序启动后创建的第一个对象就是UIApplication对象

利用UIApplication对象,能进行一些应用级别的操作

2、UIApplication的常用属性

设置应用程序图标右上角的红色提醒数字
@property(nonatomic) NSInteger applicationIconBadgeNumber;

设置联网指示器的可见性
@property(nonatomic,getter=isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible;

3、iOS中的状态栏

1)从iOS7开始,系统提供了2种管理状态栏的方式
通过UIViewController管理(每一个UIViewController都可以拥有自己不同的状态栏)
通过UIApplication管理(一个应用程序的状态栏都由它统一管理)

2)在iOS7中,默认情况下,状态栏都是由UIViewController管理的,UIViewController实现下列方法就可以轻松管理状态栏的可见性和样式

状态栏的样式
- (UIStatusBarStyle)preferredStatusBarStyle;

状态栏的可见性
- (BOOL)prefersStatusBarHidden;

3)如果想利用UIApplication来管理状态栏,首先得修改Info.plist的设置

4)UIApplication有个功能十分强大的openURL:方法
- (BOOL)openURL:(NSURL*)url;

openURL:方法的部分功能有

// 打电话
UIApplication *app = [UIApplication sharedApplication];
[app openURL:[NSURL URLWithString:@"tel://10086"]]; // 发短信
[app openURL:[NSURL URLWithString:@"sms://10086"]]; // 发邮件
[app openURL:[NSURL URLWithString:@"mailto://12345@qq.com"]]; // 打开一个网页资源
[app openURL:[NSURL URLWithString:@"http://www.baidu.com"]];

5)UIApplication单例

单例就是无论怎么创建都只能有一个实例对象
如果地址相同就代表着是同一个实例对象
一般情况下创建一个单例对象都有一个与之对应的类方法
一般情况下用于创建单例对象的方法名称都以share开头, 或者以default开头

// 获取应用程序的象征
UIApplication *app = [UIApplication sharedApplication];

下面模仿苹果内部原理写一个单例对象

#import <Foundation/Foundation.h>

@interface Person : NSObject
+ (instancetype)sharedPerson;
@end #import "Person.h"
@implementation Person static Person *p = nil; // 程序启动的时候,就马上创建一个person
// 怎么才能知道程序启动? // 作用:加载类到内存
// 什么时候调用:程序一启动就会加载类到内存
// 只会调用一次,类只需要加载一次
+ (void)load
{
// 创建person对象
[self sharedPerson];
} + (instancetype)sharedPerson
{ // 代码块里面的东西只会执行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"dispatch_once");
p = [[self alloc] init]; }); // 创建Person对象
return p;
} + (instancetype)alloc
{
// 第一次不需要抛异常
if (p) {
// 抛异常
// Name:异常的名称
// reason:异常的原因
NSException *exce = [NSException exceptionWithName:@"NSInternalInconsistencyException" reason:@"There can only be one Person instance." userInfo:nil]; [exce raise];
}
return [super alloc];
}
@end

三、UIApplication和delegate


1、所有的移动操作系统都有个致命的缺点:app很容易受到打扰。比如一个来电或者锁屏会导致app进入后台甚至被终止

还有很多其它类似的情况会导致app受到干扰,在app受到干扰时,会产生一些系统事件,这时UIApplication会通知它的delegate对象,让delegate代理来处理这些系统事件

delegate可处理的事件包括:
应用程序的生命周期事件(如程序启动和关闭)
系统事件(如来电)
内存警告

2、UIApplicationDelegate协议

// app接收到内存警告时调用
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application;
// app进入后台时调用(比如按了home键)
- (void)applicationDidEnterBackground:(UIApplication *)application;
// app启动完毕时调用
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;

3、UIApplicationDelegate
每次新建完项目,都有个带有“AppDelegate”字眼的类,它就是UIApplication的代理
默认已经遵守了UIApplicationDelegate协议,已经是UIApplication的代理

四、iOS程序的启动过程


UIApplicationMain

main函数中执行了一个UIApplicationMain这个函数

int UIApplicationMain(int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName);
argc、argv:直接传递给UIApplicationMain进行相关处理即可

principalClassName:指定应用程序类名(app的象征),该类必须是UIApplication(或子类)。如果为nil,则用UIApplication类作为默认值

delegateClassName:指定应用程序的代理类,该类必须遵守UIApplicationDelegate协议

UIApplicationMain函数会根据principalClassName创建UIApplication对象,根据delegateClassName创建一个delegate对象,并将该delegate对象赋值给UIApplication对象中的delegate属性

接着会建立应用程序的Main Runloop(事件循环),进行事件的处理(首先会在程序完毕后调用delegate对象的application:didFinishLaunchingWithOptions:方法)

程序正常退出时UIApplicationMain函数才返回

五、UIWindow


1、UIWindow是一种特殊的UIView,通常在一个app中至少会有一个UIWindow

iOS程序启动完毕后,创建的第一个视图控件就是UIWindow,接着创建控制器的view,最后将控制器的view添加到UIWindow上,于是控制器的view就显示在屏幕上了

一个iOS程序之所以能显示到屏幕上,完全是因为它有UIWindow

也就说,没有UIWindow,就看不见任何UI界面

2、添加UIView到UIWindow中两种常见方式:
- (void)addSubview:(UIView *)view;
直接将view添加到UIWindow中,但并不会理会view对应的UIViewController

@property(nonatomic,retain) UIViewController *rootViewController;
自动将rootViewController的view添加到UIWindow中,负责管理rootViewController的生命周期

常用方法
- (void)makeKeyWindow;
让当前UIWindow变成keyWindow(主窗口)

- (void)makeKeyAndVisible;
让当前UIWindow变成keyWindow,并显示出来

3、UIWindow的获得
[UIApplication sharedApplication].windows
在本应用中打开的UIWindow列表,这样就可以接触应用中的任何一个UIView对象
(平时输入文字弹出的键盘,就处在一个新的UIWindow中)

[UIApplication sharedApplication].keyWindow
用来接收键盘以及非触摸类的消息事件的UIWindow,而且程序中每个时刻只能有一个UIWindow是keyWindow。如果某个UIWindow内部的文本框不能输入文字,可能是因为这个UIWindow不是keyWindow

view.window
获得某个UIView所在的UIWindow

四大对象的关系

最新文章

  1. iOS 子视图超出父视图范围点击事件处理!
  2. 【bzoj4027】[HEOI2015]兔子与樱花
  3. Could not load file using Ranorex runtime : General Questions
  4. visual studio 2012如何彻底删除TFS上的团队项目
  5. Flex中NetConnection与NetStream的关系、及浏览器并发连接数测试[转]
  6. HeadFirst设计模式读书笔记(5)-单例模式
  7. 超强1000 JQuery插件
  8. Javascript使用postMessage对iframe跨域通信
  9. java中的日期处理
  10. One Card Poker
  11. for循环购物清单
  12. 《iOS Human Interface Guidelines》——Multitasking
  13. 基于GPS数据建立隐式马尔可夫模型预测目的地
  14. 安装nova后解决登录没账号问题
  15. LeetCode 104. Maximum Depth of Binary Tree C++ 解题报告
  16. vue $refs的基本用法
  17. Java常用的九种排序方法及代码实现
  18. 分类统计的controller和service
  19. Struts2输入校验(编码方式)
  20. TCP:WireShark分析,序列号Seq和确认号Ack

热门文章

  1. JS-DOM2级事件对象跨浏览器处理(已封装)
  2. 谁都能看懂的单点登录(SSO)实现方式(附源码)
  3. DataReader和DataSet的异同
  4. ORACLE 错误:oralce record is locked by another user
  5. typedef和#define的用法与区别
  6. Http请求之--C#的HttpWebRequest实现POST方式请求
  7. cmd 导出目录树
  8. GLEW OpenGL Access violation when using glGenVertexArrays
  9. [ngRepeat:dupes] Duplicates in a repeater are not allowed. Use &#39;track by&#39; expression to specify uniq
  10. 为你的Visual Studio单独设置代理服务器