iOS开发之旅之App的生命周期

在iOS App中,入口函数并不在根目录下,而是在“Supporting Files”目录的main.m文件的main函数中。这很容易理解,C/C++都是以main为入口。

int main(int argc, char * argv[]) {
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

这个函数比较简单,只是调用了UIApplicationMain方法来启动整个应用程序,前两个参数就是普通C/C++的命令行参数,这里我们可以忽略。主要看后面两个参数。后两个参数分别表示程序的主要类(principal class)和app代理类(delegate class)。如果主要类(principal class)为nil,将从Info.plist中获取,如果Info.plist中不存在对应的key,则默认为UIApplication;App代理类(delegate class)将在新建工程时创建,即AppDelegate,应用程序的整个生命周期都由它来代理。

APP生命周期

根据UIApplicationMain函数,程序将进入AppDelegate.m,这个文件是xcode新建工程时自动生成的。下面看一下AppDelegate.m文件,这个关乎着应用程序的生命周期。

#import "AppDelegate.h"
@interface AppDelegate ()
@end

@implementation AppDelegate
// 应用程序第一次启动时执行该函数,如果是手写代码设置应用程序window的rootViewController那么则需要在这里实现。该函数的功能等同于Android中的onCreate函数。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    return YES;
}
// 应用程序由激活状态切换到未激活状态要执行的函数,例如用户按home键返回主屏幕等。类似于Android中的onPause回调函数
- (void)applicationWillResignActive:(UIApplication *)application {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
// 应用程序已进入后台程序时的回调函数,类似于Android中的onStop
- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
// 应用程序从未激活状态进入到激活状态要执行的回调函数,过程与WillResignActive相反,等同于Android中的onRestart函数。
- (void)applicationWillEnterForeground:(UIApplication *)application {
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
// 应用程序被激活的回调,与didEnterBackground过程想对应。onResume
- (void)applicationDidBecomeActive:(UIApplication *)application {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
// 应用程序即将终止的回调函数
- (void)applicationWillTerminate:(UIApplication *)application {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

图1 图2

如上图1所示,应用程序启动UIApplication,此时主线程( UI线程 )的事件循环就会开启。并且会将App的生命周期代理给AppDelegate,首先会调用

(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions ,我们又会在该函数中设置AppDelegate中window的rootViewController为我们的第一个页面(更多的情况是系统自动加载应用程序的默认的storyboard界面),我们会在自己的ViewController中设计UI,因此应用程序window中就加载了我们的UI,此时应用程序就从最初的not running状态到了Active状态。

UI的线程安全

在上文中我们提到了应用程序启动时会启动一个消息循环,并且这个消息循环是在主线程中的。开发过Android应用程序的同学都知道,更新UI必须在主线程中,这是因为UI控件并不是线程安全的,在Android中UI控件都是ThreadLocal的,这个ThreadLocal就是就是主线程的ThreadLocal,可以简单的理解为UI控件的操作只能在主线程中执行才是安全的,如果在其他线程中操作就会抛出异常,这就是UI控件的非线程安全性。

iOS中的UI控件也不是线程安全的。因为App中UI更新频率时是很高的,如果UI是线程安全的,也就是UI控件在子线程中可以修改、更新等,那么系统必须要对各种UI操作进行锁操作,加锁、解锁、系统调度等会消耗大量的CPU资源,这样就会导致效率底下,而且容易导致死锁问题。因此,UI操作只能在主线程中。官方解释如下 :

Threading ConsiderationsManipulations to your application’s user interface must occur on the main thread. Thus, you should always call the methods of the UIView class from code running in the main thread of your application. The only time this may not be strictly necessary is when creating the view object itself but all other manipulations should occur on the main thread.

UIWindow与UIView

UIWindow就是应用程序窗口,简单理解就是整个手机屏幕。UIWindow的主要功能就是提供一个区域来显示UI视图和将事件分发给视图。在应用加载时,我们会设置或者由系统从plist文件中加载UIWindow的rootViewController,在UIViewController中又包含了各种UI控件,当应用启动时,启动了消息循环,回调App的生命周期函数,将UI控件绘制到UIWindow中,然后又通过UIWindow将用户的各种操作通过事件的形式分发给UI控件,至此整个App就运转起来了。

参考文档 : https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html#//apple_ref/doc/uid/TP40007072-CH2-SW1

时间: 2024-07-30 10:14:22

iOS开发之旅之App的生命周期的相关文章

OS开发之旅之App的生命周期【转载】

原文链接 http://www.360doc.com/content/15/0918/14/27799428_499912639.shtml 在iOS App中,入口函数并不在根目录下,而是在“Supporting Files”目录的main.m文件的main函数中.这很容易理解,C/C++都是以main为入口. int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, 

【iOS】app的生命周期

对于iOS应用程序,关键的是要知道你的应用程序是否正在前台或后台运行.由于系统资源在iOS设备上较为有限,一个应用程序必须在后台与前台有不同的行为.操作系统也会限制你的应用程序在后台的运行,以提高电池寿命,并提高用户与前台应用程序的体验.当应用程序在前台和后台之间切换时,操作系统将会通知您的应用程序.你可以通过这些通知来修改你的应用程序的行为. 当你的应用程序在前台活动时,系统会发送触摸事件给它进行处理.在UIKit的基础设施做了大部分的事件传递给你的自定义对象工作.所有您需要做的是覆盖在相应的

iOS开发之剖析"秘密"App内容页面效果(二)

@前些天写了一篇"秘密"的Cell效果文章,但是与在工作中想要的效果还是有差距,而且扩展性很不好,于是重写封装,把整体视图都放到scrollView中,基本是和secret app 一模一样的效果了. @代码如下:(模糊效果的类就不写了,大家可以搜"UIImage+ImageEffects",还要导入Accelerate.framework) 1.MTSecretAppEffect.h #import <Foundation/Foundation.h>

iOS开发之剖析&quot;秘密&quot;App内容页面效果

最近在玩"秘密",发现点击主界面的Cell进去后的页面效果不错,就写了个Demo来演示下. 它主要效果:下拉头部视图放大,上拉视图模糊而且到一定位置固定不动,其他Cell可以继续上移. @封装的主要效果类:MTHeadEffect.m(.h文件省略,很简单的) #import "MTHeadEffect.h" #import <QuartzCore/QuartzCore.h> #import <Accelerate/Accelerate.h>

iOS开发实用技巧—打包app发给测试人员测试

iOS开发实用技巧—打包app发给测试人员测试 说明:在项目开发过程中经常需要开发人员将项目打包成ipa包后,发给测试人员进行测试.本文贴图对打包的过程简单介绍. 一.Product ->archive (注意,不能是模拟器状态,如果当前调试状况是模拟器的话,则archive为灰色不可点击) 模拟器情况下: 剩余步骤: 选择 证书 生成ipa包 保存 注意:在打包的同时保存xcarchive文件,以备将来查看应用的crash日志.

ios开发 上传到App Store 时出错. iTunes Store Operation Failed, An Error occurred uploading to the iTunes store.

ios开发 上传到App Store 时出错. iTunes Store Operation Failed,    An Error occurred uploading to the iTunes store. 的解决方法,网上找了很多. 如下(当然没有解决我的问题,可以一试): 今天在提交app的时候,最后一步报错, An error occurred uploading to the iTunes Store! 后来上网查了查资料,在这里整理一下: 第一: 有可能是中文编码的问题,需要把编

iOS系列 基础篇 03 探究应用生命周期

iOS系列 基础篇 03 探究应用生命周期 目录: 1. 非运行状态 - 应用启动场景 2. 点击Home键 - 应用退出场景 3. 挂起重新运行场景 4. 内存清除 - 应用终止场景 5. 结尾 本篇主要探讨的是iOS应用中各种状态的跃迁过程,建议大家通过修改AppDelegate.swift,在每个过程中添加日志输出代码,从而观察其变化. 作为应用程序的委托对象,AppDelegate类在应用程序生命周期的不同阶段会回调不同的方法. 首先,咱们先来了解一下iOS应用的不同状态和他们之间的关系

BEGINNING SHAREPOINT&#174; 2013 DEVELOPMENT 第12章节--SP 2013中远程Event Receivers 远程Event Receivers App级别生命周期

BEGINNING SHAREPOINT? 2013 DEVELOPMENT 第12章节--SP 2013中远程Event Receivers  远程Event Receivers App级别生命周期 微软在新的云App模型中对Apps生命周期的管理投入了大量的投资.

Android App的生命周期是什么

怎么说呢 看Android一般指的是 Activity的生命周期, 关于app的生命周期, 有明白的大神请告诉我 上面这张图是 网上搜到的一张关于app生命周期的图, 在我看来, 其实就是一个Actiivty的生命周期图 来源: http://blog.163.com/[email protected]/blog/static/11470228720101144447914/