iOS 应用程序运行流程

iOS程序启动原理

Posted on December 28th, 2013



iOS  程序启动原理  

技术博客 http://www.cnblogs.com/ChenYilong/    新浪微博http://weibo.com/luohanchenyilong 
  
iOS  应用程序运行流程  




UIApplicationMain  
        main.m     main   函数中执行了   UIApplicationMain   这个方法,这 是   ios   程序的入口点     
  intUIApplicationMain  (intargc,char*argv[], NSString *principalClassName, NSString *delegateClassName)     
      argc    argv  :   ISO C   标准   main   函数的参数,直接传递 给   UIApplicationMain   进行相关处理即可     
      principalClassName  :指定应用程序类,该类必须 是   UIApplication   (   或子类   )   。如果为   nil,   则用   UIApplication   类 作为默认值     
      delegateClassName  :指定应用程序类的代理类,该类必须遵 守 UIApplicationDelegate   协议     

UIApplicationMain  
     此函数会根据   principalClassName   创建   UIApplication      对象,根据 delegateClassName   创建一个   delegate   对象 ,并将该   delegate   对象赋值给 UIApplication   对象中 的   delegate   属性  
     UIApplication   对象会依次给   delegate   对象发送不同的 消息,接着会建立应用程序的   main runloop   (事件循环) ,进行事件的处理   (   首先会调用   delegate   对象的  
application:didFinishLaunchingWithOptions:)  
     程序正常退出时这个函数才返回。如果进程要被系统强制 杀死,一般这个函数还没来得及返回进程就终止了  


     如果设置了主   xib   文件(在   Info.plist   中指定 ,   key     NSMainNibFile   ),就会在主   xib 文件中 寻找   UIApplication   和连接它的   delegate   。因 此在主   xib   文件中,   File’s Owner 必须 为   UIApplication(   或子类   )   ,并且建立一个遵 守   UIApplicationDelegate   delegate   对象, 建立   UIApplication     delegate   对象的关联关系  
四大对象关系图  


iOS  中的   mvc 
   

UIApplication  
     UIApplication   是应用程序的核心,每一个程序在运行期必须 有   UIApplication   (或子类)的一个实例(   有且仅有一个   ),通 过   [UIApplication sharedApplication]  可以得到这个单例实例 的指针  
     UIApplication   帮助管理应用程序的生命周期,而它通过   delegate      来履行这个任务  
     UIApplication   可以接收事件,把所有用户事件都放入队列,逐个 处理,它会发送当前事件给一个合适的目标控件进行处理。它还将   部分      事件转给   delegate   对象来处理 ,delegate   可处理的事件包括:应用程 序的生命周期事件   (   如程序启动和关闭   )   、系统事件   (   如来电   )  


UIApplication  
     [UIApplication sharedApplication].windows  :      在本应用中打开的   UIWindow 列表,这样就可以接触应用  
中的任何一个   UIView   对象  
     [UIApplication sharedApplication].keyWindow  :      用来接收   键盘   以及   非触摸类 的消息事件的   UIWindow   ,而  
且程序中每个时刻只能有一个   UIWindow     keyWindow        如果某个   UIWindow   内部的文本框不能输入文字,可能是 因为这个   UIWindow   不是   keyWindow  

下面是这个类的一些功能:  
1.   设置   icon   上的数字图标  
//   设置主界面   icon   上的数字图标,在   2.0   中引进,      缺省为   0  
[UIApplicationsharedApplication].applicationIconBadgeNumber = 4;  
2.  
设置摇动手势的时候,是否支持   redo,undo   操作  
//  
摇动手势,是否支持   redo undo   操作。  
//3.0  
以后引进,缺省   YES  
[UIApplicationsharedApplication].applicationSupportsShakeToEdit =  
YES   ;  
3.   判断程序运行状态  
//   判断程序运行状态,在   2.0   以后引入  
/*  
UIApplicationStateActive,  
UIApplicationStateInactive,  
UIApplicationStateBackground  
*/  
if([UIApplicationsharedApplication].applicationState ==UIApplicationStateInactive){  
NSLog(@"  
程序在运行状态   ");  
}  
4.  
阻止屏幕变暗进入休眠状态  
//  
阻止屏幕变暗,慎重使用   ,   缺省为   no 2.0  
[UIApplicationsharedApplication].idleTimerDisabled =YES;  
(慎重使用本功能,因为非常耗电)  
5.  
显示联网状态  
//  
显示联网标记      2.0  
[UIApplicationsharedApplication].networkActivityIndicatorVisible =YES;  

6.     map   上显示一个地址  
NSString* addressText =  
@"1 Infinite Loop, Cupertino, CA 95014"   ;  
// URL encode the spaces  
addressText= [addressTextstringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];  
NSString* urlText = [NSStringstringWithFormat:@"  
http://maps.google.com/maps?q=%@   ", addressText];  
[[UIApplicationsharedApplication]openURL:[NSURLURLWithString:urlText]];  

7.   发送电子邮件  
NSString *recipients =  
@"mailto:first@example.com?cc=second@example.com,third@example.com&subject=Hello from California!"   ;  
NSString *body =  
@"&body=It is raining in sunny California!"   ;  
NSString *email = [NSStringstringWithFormat:  
@"%@%@"   , recipients, body];  
email = [emailstringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];  
[[UIApplicationsharedApplication]openURL:[NSURLURLWithString:email]];  
8.   打电话到一个号码  
// Call Google 411  
[[UIApplicationsharedApplication]openURL:[NSURLURLWithString:@" tel://8004664411 "]];  

9.   发送短信  
// Text to Google SMS  
[[UIApplicationsharedApplication]openURL:[NSURLURLWithString:@"sms://466453"]];  

10.   打开一个网址  
// Lanuch any iPhone developers favsite  
[[UIApplicationsharedApplication]openURL:[NSURLURLWithString:@" http://itunesconnect.apple.com "]]; 

UIApplicationDelegate  
     在开发过程中,   UIApplication   是一个非常重要的全局对象。但在实 际编程中我们并不直接和   UIApplication   对象打交道,而是和其代理 打交道,它的代理必须遵守 UIApplicationDelegate  协议,代理   ��      供了相关的生命周期方法来处理应用程序的系统事件  
>  
         ios   设备的内存极其优先,如果为   app   分配了太多内存,操作系统会终 止   app   的运行,在   UIApplication   接收到这个事件后它会调用代理 的 applicationDidReceiveMemoryWarning  方法,代理在这个方 法内可以进行释放内存的操作以防止操作系统强制终止应用程序的运行  
>  
  
>  
    UIApplicationDelegat  
>  
          ios   并不是多任务的操作系统,所以   app   很容易受到打扰。比如一个来 电可能导致   app   失去焦点,如果这个时候接听了电话,那么   app   会自动 终止运行     
>  
          还有很多其它类似的事件会导致   app   失去焦点  
>  
          app   失去焦点前   会调用代理的   applicationWillResignActive     
>  
          app   再次获取焦点   时会调用代理的   applicationDidBecomeActive     
>  
          在运行   app     锁屏   会调用代理的   applicationWillResignActive     
>  
            屏幕被解锁   时,会调用代理的   applicationDidBecomeActive  
>  
    UIApplicationDelegate   生命周期方法说明  
>  
    1     - (   void   )applicationWillResignActive:(UIApplication *)application    
> / /  
从主动到非活动状态的应用程序时发送。这可导致产生某些类型的临时中断(如传入电话呼叫或   SMS   消息)       ,或者当用户退出应用程序,它开始过渡到的背景状态。  
>     / /  
使用此方法暂停正在进行的任务,禁用定时器,踩下油门,   OpenGL ES   的帧速率。游戏应该使用这种方法来暂停游戏。  
>  
     
>  
    2     - (   void   )applicationDidBecomeActive:(UIApplication *)applicatio  
>  
    说明:当应用程序入活动状态执行,这个刚好跟上面那个方法相反  
>  
    3     - (   void   )applicationDidEnterBackground:(UIApplication *)application    
>  
    说明:当程序被推送到后台的时候调用。所以要设置后台继续运行,则在这个函数里面设置即可  
> / /  
使用这个方法来释放共享资源,保存用户数据,废止定时器,并存储足够的应用程序状态信息的情况下被终止后,将应用程序恢复到目前的状态。  
>     / /  
如果你的应用程序支持后台运行,这种方法被调用,而不是 applicationWillTerminate    :当用户退出。  
>  
     
>  
    4     - (   void   )applicationWillEnterForeground:(UIApplication *)applicatio  
>  
    说明:当程序从后台将要重新回到前台时候调用,这个刚好跟上面的那个方法相反。  
>  
    5     - (   void   )applicationWillTerminate:(UIApplication *)applicatio  
>  
    //   不支持多任务的时候调用  
>  
>  
    说明:当程序将要退出是被调用,通常是用来保存数据和一些退出前的清理工作。这个需要要设置   UIApplicationExitsOnSuspend   的键值(自动设置)。  
>  
    6     - (   void   )applicationDidReceiveMemoryWarning:(UIApplication *)applicatio  
>  
    说明:   iPhone   设备只有有限的内存,如果为应用程序分配了太多内存操作系统会终止应用程序的运行,在终止前会执行这个方法,通常可以在这里进行内存清理工作防止程序被终止  
>  
    7     - (   void   )applicationSignificantTimeChange:(UIApplication*)applicatio  
>  
    说明:当系统时间发生改变时执行  
>  
    8     - (   void   )applicationDidFinishLaunching:(UIApplication*)applicatio  
>  
    说明:当程序载入后执行  
>  
    9     - (   void   )application:(UIApplication)application willChangeStatusBarFrame:(CGRect)newStatusBarFram  
>  
    说明:当   StatusBar   框将要变化时执行  
>  
    10     - (   void   )application:(UIApplication*)application willChangeStatusBarOrientation  
> (UIInterfaceOrientation)newStatusBarOrientatio  
> duration:(NSTimeInterval)duratio  
>  
    说明:当   StatusBar   框方向将要变化时执行  
>  
    11     - (   BOOL   )application:(UIApplication*)application handleOpenURL:(NSURL*)ur  
>  
    说明:当通过   url   执行  
>  
    12     - (   void   )application:(UIApplication*)application didChangeStatusBarOrientation:(UIInterfaceOrientation)oldStatusBarOrientatio  
>  
    说明:当   StatusBar   框方向变化完成后执行  
>  
    13     - (   void   )application:(UIApplication*)application didChangeSetStatusBarFrame:(CGRect)oldStatusBarFram  
>  
    说明:当   StatusBar   框变化完成后执行  
>  
  
>  
    UIWindow 
>  
          UIWindow   是一种特殊的   UIView   ,通常在一个   app   中只会有一 个   UIWindow   ,但可以手动创建多个   UIWindow     
>  
          UIWindow   的主要作用   :     
>  
    1        供一个区域来显示视  
>  
    2      将事件分发给视  
>  
    3        UIViewController   协同工作,方便完成设备方向旋转的支持  
>  
  
>  
    UIWindow 
★    添加 UIView 到 UIWindow 中两种常见方式 : 
>     1     addSubview :直接将 UIView 添加到 UIWindow 中,程序负责维 护 UIView 的生命周期以及刷新,但并不会理会 UIView 对应 的 UIViewController 
>     2     rootViewController :自动将 UIViewController 对应的 UIView    添加到UIWindow 中,同时负责维护 UIViewController 和 UIView 的 生命周期 
>     ★    常用方  
>     1     makeKeyWindow : 让当前 UIWindow 变成 keyWindo  
>     2     makeKeyAndVisible : 让当前 UIWindow 变成 keyWindow ,并显示出来 
>    
>      UIViewControlle  
>  
   ★    UIViewController 属于 MVC 模型中的 C(Controller), 说的更具体 点它是一个视图控制器 , 管理着一个视图 (UIView) 
>     ★    一个 UIViewController 应该只管理一个 view hierarchy ,通常 来说一个完整的view hierarchy 指的是占满整一个屏幕。而很多 ap p 满屏中会有各个区域分管不同的功能,一些开发者喜欢直接新建一 个 UIViewController 和一套相应的 view 来完成所要的功能,这样 做完全不符合 Apple �� 供的设计规范 UIViewController 的  view

★    可以利用 xib 文件来初始化 view;    也可以使用自定义 的  view ,那就必须覆盖loadView 方法来创建这个 view ★  UIViewController 的 view 是 lazy loading 的 , 当你访 问其 view 属性时 ,view 会从 xib 文件载入或者通过代码创 建 ( 覆盖 loadView 方法, 自定义其 view hierarchy) ★   可以用 isViewLoaded 方法判断一个 UIViewController   的 view 是否已经被加载UIViewController 生命周期方法的  
r>     ★    当 view 加载后调用 viewDidLoad , 这里可以进行一些数据的请求或加载 ,  用来更新界面 ★ 当 view 将要被加入 view hierarchy 时调用 viewWillAppear , 完成  加入时调用  viewDidAppear    ★ 当 view 将要从 view hierarchy 中移除时调用viewWillDisappear  ,  完成移除时调用 viewDidDisappear    ★   当内存紧张时 ,    调用didReceiveMemoryWarning , 其默认实现是如 果当前 UIViewController 的 view 的superview 是 nil, 则将 view 释 放且调用 viewDidUnload ,    viewDidUnload 中你可以进行后继的内 存清理工作 ( 主要是界面元素的释放 , 当再次加载的时候需要重建 )  (这里的  view 是指 UIViewController 内部的 view 属性)  工程名  -Info.plist

★   建立一个工程后,会在 Supporting files 文件夹下看到一个 ” 工程名    -Info.plist” 的文件,该文件对工程做一些运行期的配置,很重要, 不能删除    ★   在旧版本 Xcode 创建的工程中,这个配置文件的名字就叫 ” Info.plist ”

★   如果使用文本编辑器打开这个文件,会发现这是一个 XML 格式的文本  文件,一般不用文本编辑器直接编辑这个文件,而是通过  Xcode 编辑

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

★   常见属性 ( 红色部分是用文本编辑器打开时看到的 key)

★   Localiztion native development region( CFBundleDevelopmentRegion ) -本地化相关    ★   Bundle display name( CFBundleDisplayName ) - 程序安装后显 示的名称 , 限制在 10 - 12 个字符,如果超出,将被显示缩写名称

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

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

★   Main nib file base name( NSMainNibFile ) - 主 nib 文件的名称

★   Bundle identifier( CFBundleIdentifier ) - 项目的唯一标识, 部署到真机时用到  工程名  -Prefix.pch

★   一般来说,可以将项目中经常用到的一些头文件放在这里来 import , 整个项目都可以访问这个文件的内容,这样既节省了手动添加 import 的时间,也有助于加速编译

★   在这里定义的宏,整个项目都可以访问    ★ 在 pch 文件中添加下列预处理指令,然后在项目中使用 Log(...) 来输出 日志信息,就可以在发布应用的时候,一次性将 NSLog语句移除(在调 试模式下,才有定义 DEBUG )  #ifdef DEB  
r> #define   Log(...) NSLog(__VA_ARGS_  
r>     #el  
r> #define     Log(...)    /*  
r>     #end  
r>     r>   

开发iOS6 的注意

★    iOS6 新特性: auto layout 属性,此属性只针 对 iOS6 及以上版本 ★    iOS6 以下版本运行时可能会出现的异常信息: Terminating app due to uncaug  
r> excepti  
r> ‘NSInvalidUnarchiveOperationException  
r> reason: ‘Could not instantiate cla  
r> named NSLayoutConstrain  
r>     ★    具体场景: Xcode 4.5    选择 iPhone/iPad 5.0/5.1 Simulator (模拟器) ★    解决办法:需要关闭 storyboard 或 xib 界面文 件的 Use Autolayout    选项,这是因为 AutoLayout 特性是 iOS 6 新增加的,在之前的    5.0/5.1 Simulator 模拟器中不支持nib 文件

★   nib 文件是 iOS 中用来 表 述视图的 xml 格式的 文本文件, 现在拓展名为 xib ,用Interface Builder 打开可以 生成图形界面式的 表 述

★   某书中著名的一句话 :Interface Builder 把窗口、 菜单栏以及窗口上的各种控件对象都 ” 冻结 ” 在一个 NIB    文件里 ; 程序运行时,这些对象将会 ” 苏醒 ”

★   加载 Nib 文件时,会将文件中的 表 述转化为应用程序可 以操作的真正对象,所有在 Interface Builder 中建 立的关联(如 File’s Owner 和其他对象之间的关联) 都能够在运行时重新建立起来   主  nib 文件

★   主 nib 文件是指应用程序一启动就装载的 nib 文件,它 的 File’s Owner 一定要是个 UIApplication( 或子类 )    ,并且新建一个 delegate 对象、建立 UIApplication    和delegate 对象的关联主  nib 文件的设置方法 r>    ★ 在 Info.plist 通过 NSMainNibFile 这个 key 可以设置主 nib 文件主  nib 文件的设置方法 
r>  
   在 Summary 的 Main Interface 中  
r>   UIView ★   UIView 是 iOS 中界面元素的基础,所有的界面元素都继承它,可以说 在iPhone 中你能看到的、摸到的,都是 UIView ★   UIView 的基本功  
r>     1    绘图和动画 ( 用 CALayer 和 CAAnimation 实现 
r>     2    事件处理 ( 继承了 UIRsponde  
r>     ★    一个 UIView 可以包含和管理若干个子视图,决定着子视图的位置和大小UIView 常用属性

★   frame 在  父视图 坐标系中的位置 (CGPoint origin) 和大小 (CGSize size)

★   bounds 在  本视图 坐标系中的位置 (CGPoint origin 的 x 、 y 永远为 0) 和大 小(CGSize size)

★   center  
视图的中点在 父视图 坐标系中的  
r>     ★    UIView*superview 父  
r>     ★    NSArray*subviews 所有的子  
r>     ★    UIWindow *window    当前视图所在的  
r>     ★    BOOLuserInteractionEnabled YES 代表接收触摸事件    •    在父视图坐标系中,父视图的左上角为坐标原点 (0,  
r>     •    在本视图坐标系中,本视图的左上角为坐标原点 (0, 0)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值