1、项目经常使用文件及文件夹
1>Products文件夹:主要用来放Mac开发的可执行文件。对手机应用开发来讲彻底没用
2>Frameworks文件夹:当前开发依赖的一些框架和库。如Foundation框架,UIKit框架,CoreGraphics框架,test框架
3>工程名+Tests文件夹:用来作单元测试的,写好某一小块功能以后,能够在这里面写相应的代码来测试我写好的这个函数或者写好的这个功能是否正确
4>支持文件夹下的 工程名--info.plist文件 :是应用程序的一个配置文件,该文件对工程作一些运行期的配置,很是重要,不能删除
*项目中其余plist文件不能带有"Info"这个字眼,否则会被错认为是传说中很是重要的"Info.plist"。
*项目中含有一个InfoPlist.strings的文件,跟Info.plist文件的本地化相关
info.plist常见设置(这些均可以在工程文件左边栏第一个的General里可视化设置)
Bundle display name:显示在桌面上的应用的名称(若更名那么先删掉这个应用而后Clean一下,再运行。否则可能会有缓存,用的仍是上次的plist文件)
Bundle identifier:程序的惟一标识(发布应用,真机调试,安装应用都会用到),若是有2个应用的程序标识同样,那么后安装的会覆盖前安装的程序。如cn.baidu
问:为何域名要倒过来写?
答:由于域名是惟一的,若是百度和谷歌都开发地图,那么两个map就会有一个被覆盖。因此将域名倒过来写com.baidu.map,com.google.map就不会覆盖了。
Bundle version.string.short:苹果商店的正式版本(后一次必定要比前一次大)
Bundle version:内部版本
Main storyboard file base name:Main 那么之后就会加载Main.storyboard
plist文件经过xml保存,xml是用来保存数据的(经过字典键值对的形式保存)
5>支持文件夹下的 工程名--Prefix.pch文件(也是一个头文件)
*pch头文件的内容能被项目中的其余全部源文件共享和访问
用途:
A.通常在pch文件中定义一些全局的宏,或导入一些全局都能用到的头文件
B.用来自定义Log(不会这个就等于你没有开发经验)
在开发中分为两个阶段
1.开发调试阶段:是须要打印LOG调试程序的,若是程序处于调试阶段,系统会为咱们定义一个名为DEBUG的宏
2.发布阶段:不须要打印LOG,由于LOG很占用资源而且用户看不懂LOG,若是程序处于发布阶段,系统就会自动删除名为DEBUG的宏
因此须要自定义LOG
*在pch文件中添加下列预处理指令(写在#ifdef __OBJC__和#endif之间),而后在项目中使用NJLog(...)来输出日志信息,就能够在发布应用的时候,一次性将NSLog语句移除(在调试模式下,才有定义DEBUG)
#ifdef DEBUG
#define NJLog(...)NSLog(__VA_ARG5__)//将自定义宏替换成系统宏
#else
#define NJLog(...) //表示这个自定义宏什么都不替换,因此以前全部用NJLog打印的语句都变成了空白。
#endif
//PS:三个点...表明可变参数缓存
pch文件里默认代码的说明
//在全部的.m文件和.mm文件中默认就定义了__OBJC__这个宏,默认导入2个框架
#ifdef __OBJC__
//若是这个全局的头文件或者宏只须要在.m文件和.mm文件中使用,请把该头文件或宏写到#ifdef __OBJC__和#endif之间
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#endif网络
之后工做第一件事就是打开pch文件,查看公司自定义的LOG是什么,而后使用公司自定义的LOG,永远不要使用系统LOG。app
2、4大对象框架
对象1:UIApplication
:ide
1.获取UIApplication函数
UIApplication *app = [UIApplication sharedApplication]; UIApplication *app1 = [UIApplication sharedApplication]; //app和app1的地址是相同的。证实只有一个UIApplication对象 //UIApplication *app2 = [UIApplication alloc] init];//这句会报错,由于只能有一个UIApplication对象,不能再建立
2.在View上添加一个按钮,当点击按钮时作应用级别的操做单元测试
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100,100,100,100)]; [btn setTitle:@"点我啊" forState:UIControlStateNormal]; [btn addTarget:self action:@selector(onClick) forControlEvents:UIControlEventTouchUpInside]; btn.backgroundColor = [UIColor redColor]; [self.view addSubview:btn];
-(void)onClick { UIApplication *app = [UIApplication sharedApplication]; //桌面图标左上角就会显示红色的998标签,表明有新的消息 app.applicationIconBadgeNumber = 998; //状态栏上的小菊花(联网动画) app.networkActivityIndicatorVisible = YES; }
3.修改状态栏样式(设置状态栏是否隐藏同理)
方法一:经过控制器修改状态栏(适用于应用中包含多种样式状态栏的状况)测试
-(UIStatusBarStyle)preferredStatusBarStyle { return UIStatusBarStyleLightContent; }
方法二:经过UIApplication修改状态栏(适用于应用中状态栏样式不变的状况)
1>先在Info.Plist文件中添加一个属性View controller-based status bar appearance,并设置为NO
2>app.statusBarStyle = UIStatusBarStyleLightContent;
下面的方法还能够设置动画
[app setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];动画
/* URL:统一资源定位符,用来惟一地表示一个资源 URL:协议头://主机地址/资源路径 网络资源:http://www.baidu.com/images/20140603/abc.png 本地资源:file://users/apple/desktop/abc.png */ NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"]; [app openURL:url]; //系统会自动判断资源类型而且使用适当应用打开
对象2:UIApplicationDelegategoogle
对象3:UIWindow
#pragma mark - 代理方法 //当应用程序启动完毕的时候就会调用(系统自动调用,且只调用一次,退到后台再启动就不会再调用了) -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { return YES; } //即将失去活动状态的时候调用(失去焦点,不可交互) -(void)applicationWillResignActive:(UIApplication *)application { } //应用程序进入后台的时候调用 //通常在该方法中保存应用程序的数据,以及状态 -(void)applicationDidEnterBackground:(UIApplication *)application { } //应用程序即将进入前台的时候调用 //通常在该方法中恢复应用程序的数据,以及状态 -(void)applicationWillEnterForeground:(UIApplication *)application { } //从新获取焦点(可以和用户交互) -(void)applicationDidBecomeActive:(UIApplication *)application { } //应用程序即将被销毁的时候会调用该方法 //注意:若是应用程序处于挂起状态的时候没法调用该方法 -(void)applicationWillTerminate:(UIApplication *)application { } //应用程序接收到内存警告的时候就会调用 //通常在该方法中释放掉不须要的内存 -(void)applicationDidReceiveMemoryWarning:(UIApplication *)application { }
UIWindow的建立
系统会在didFinishLaunchingWithOptions:方法中自动建立UIWindow,设置其背景色为白色,并将UIWindow显示出来。
建立一个空Application就能够看到这些细节,但须要本身建立控制器(若是建立Single View Application就不须要,系统会自动建立)
方式一:将控制器view添加到UIWindow上
问题:当view发生一些事件的时候,通知控制器,可是控制器已经销毁了,因此可能出现未知错误
方式二:将Window的根控制器设置为建立的控制器
(建议使用这个方法,系统自动设置时也是这样作的。)
好处:当发生旋转事件的时候,UIApplication对象会将旋转事件传递给UIWindow,UIWindow又会将旋转事件传递给它的根控制器,由根控制器决定是否须要旋转,因此设置了根控制器就会旋转,方便用户操做。
对象4:UIViewController
3、程序启动原理
打开程序会执行main函数,由上至下执行如下代码
int main(int argc,char * argv[ ]) { /* 了解便可 argc:系统或者用户传入的参数个数 argv:系统或者用户传入的实际参数 */ return UIApplicationMain(argc,argv,nil,NSStringFromClass ([NJAppDelegate class])); /* 了解便可 1.根据传入的第三个参数建立UIApplication对象 2.根据传入的第四个参数建立UIApplication对象的代理 3.设置刚刚建立出来的代理对象为UIApplication的代理 4.开启一个事件循环(UIApplicationMain永远不会返回) */ }
iOS程序的启动过程(须要掌握)
监听系统事件,而后将事件队列(先进先出)里的事件依次处理,处理一个扔一个,有事件就处理,没事件就休息,至关于一个死循环,永远不返回。
两种状况会返回
1.被系统主动关掉
2.被用户主动关掉
笔记:
程序完整启动过程
1.main函数
|
2.UIApplicationMain(建立UIApplication及其代理,并设置代理)
|
3.没有storyboard的状况
delegate对象开始处理(监听)系统事件
*程序启动完璧的时候就会调用代理的application:didFinishLaunchingWithOptions:方法
*在application:didFinishLaunchingWithOptions:方法中建立UIWindow
*建立和设置UIWindow的rootViewController
*显示窗口
3.有storyboard的状况
根据Info.plist得到最主要storyboard的文件名,加载最主要的storyboard
*建立UIWindow
*建立和设置UIWindow的rootViewController
*显示窗口
问:为何必需要有UIWindow才能显示内容?
答:由于只有UIWindow有makeKeyAndVisible(让窗口成为主窗口并显示出来)
PS:一个应用程序只能有一个主窗口(后一个会覆盖前一个)
BUG:iOS7和iOS8里面主窗口和次窗口没区别。