iOS项目入口的演变过程(2021)

UISceneDelegate是什么,它和AppDelegate有什么关系,Swift中的@main又是什么,本文将带你一一了解。

这篇文章将主要讲解下面几点内容:

  1. iOS13之前的AppDelegate启动项目的流程
  2. UISceneDelegate的多窗口实现逻辑
  3. UISceneDelegateAppDelegate的关系
  4. int main()@main

单Window的AppDelegate

在iOS13之前iPhone上的项目都是单windows的,AppDelegate中的- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions就是iOS项目启动后第一个会被调用的函数。

作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS开发交流群:130 595 548,不管你是小白还是大牛都欢迎入驻 ,让我们一起进步,共同发展!(群内会免费提供一些群主收藏的免费学习书籍资料以及整理好的几百道面试题和答案文档!)

纯代码在AppDelegate中启动App

AppDelegate中有一个window属性,需要自己来给windows指定一个rootViewController,在不使用storyboard或者xib的情况下,最简单的AppDelegate代码大概是下面这样子:

// AppDelegate.h
@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (nonatomic) UIWindow *window;

@end

// AppDelegate.m

#import "AppDelegate.h"
#import "ViewController.h"

@interface AppDelegate ()

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.window.rootViewController = [[ViewController alloc] init];
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}

@end

AppDelegate遵守了UIApplicationDelegate协议,其中window是协议里规定的一个属性,所以这里必须在.h中声明这个属性,否则会报错[AppDelegate setWindow:]: unrecognized selector sent to instance;而如果放在.m中会报重复声明的错误Illegal redeclaration of property in class extension AppDelegate (attribute must be readwrite, while its primary must be readonly)

didFinishLaunchingWithOptions中初始化window并设置它的rootViewController之后调用makeKeyAndVisible

Storyboard在AppDelegate中启动App

如果是使用storyboard作为项目入口的话,AppDelegate就更简单了:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    return YES;
}

如果项目是使用Xcode11创建的那么要想试验这种方法需要 1. 删除info.plist中的Application Scene Manifest 2. 删除SceneDelegate.hSceneDelegate.m 3. 删除AppDelegate.m中的两个SceneDelegate相关函数application(_:configurationForConnecting:options:)application(_:didDiscardSceneSessions:) 4. 此时Xcode不会自动从Main.storyboard加载视图,我们需要通过修改didFinishLaunchingWithOptions来展示界面。

SceneDelegate

从Xcode11开始,创建新的iOS项目的模版中会带有SceneDelegate类,并且在plist文件中会有一个Application Scene Manifest配置,AppDelegate.m中新增了两个管理SceneDelegate的函数application(_:configurationForConnecting:options:)application(_:didDiscardSceneSessions:)

iOS应用的进程生命周期和UI生命周期

App的进程生命周期包括App启动、App终止等,主要涉及的协议有:

/* UIApplicationDelegate */
- (void)applicationDidFinishLaunching:(UIApplication *)application;
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(nullable NSDictionary<UIApplicationLaunchOptionsKey, id> *)launchOptions API_AVAILABLE(ios(6.0));
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(nullable NSDictionary<UIApplicationLaunchOptionsKey, id> *)launchOptions API_AVAILABLE(ios(3.0));
- (void)applicationWillTerminate:(UIApplication *)application;

App退到后台或者重新进入前台的过程属于UI生命周期,其中主要涉及的协议有:

/* UIApplicationDelegate */
- (void)applicationDidBecomeActive:(UIApplication *)application;
- (void)applicationWillResignActive:(UIApplication *)application;

SceneDelegate是什么

在iOS13之前,iOS项目只有一个主Window,那时候的进程生命周期和UI生命周期都在APPDelegate中进行管理。

在iOS13之后,为了增强iOS项目的可用性一个App可以有多个window来显示不同或相同的内容。双击设备的Home键后每一个window会独立展示。

多窗口特性只有在iPad上才可以用,iPhone上面是不行的。具体的使用方法和例子可以查看这篇苹果的官方文档

为了管理不同窗口的生命周期,苹果添加了UIWindowSceneDelegate协议,而SceneDelegate类实现了这个协议的方法,因此SceneDelegate类是用来管理iOS应用窗口的生命周期的,也就是应用界面的生命周期。

SceneDelegate和AppDelegate的关系

在推出SceneDelegate之前,整个应用的生命周期和UI生命周期都是依赖AppDelegate进行管理,在这之后,UI生命周期交给了SceneDelegate来管理,而AppDelegate就用来管理应用的生命周期和SceneDelegate的生命周期。

App的启动和杀死的回调仍然在AppDelegate中,除此之外在创建iOS项目的模版中,AppDelegate中增加了对SceneDelegate管理的两个方法:

  • application:configurationForConnectingSceneSession:options: 当窗口建立时会被调用。
  • application:didDiscardSceneSessions:sceneSessions。 当窗口被永久销毁时被调用

SceneDelegate中对App的某个窗口的动作进行管理:

scene:willConnectToSession:options:connectionOptions sceneDidDisconnect:
sceneDidBecomeActive: sceneWillResignActive:
sceneWillEnterForeground: sceneDidEnterBackground:

这里的方法都是对称出现的,基本也都是和之前在AppDelegate中的相关功能的方法很类似。

SceneDelegate承接了部分AppDelegate的功能,而AppDelegate重点用来对应用生命周期就进行管理,SceneDelegate用来管理UI生命周期。

int main()@main

在Objc项目中存在一个main.m文件,里面的main函数是项目的启动函数。

int main(int argc, char * argv[]) {
    NSString * appDelegateClassName;
    @autoreleasepool {
        // Setup code that might create autoreleased objects goos here.
        appDelegateClassName = NSStringFromClass([AppDelegate class]);
    }
    return UIApplicationMain(argc, argv, nil, appDelegateClassName);
}

在Swift中,项目入口使用@main作为标记,作用和上面的C语言函数是一样的。

/* AppDelegate.swift */
@main
class AppDelegate

通过添加@main标记,编译器会自动生成项目入口相关代码,并把AppDelegate的类名传递进去。

作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS开发交流群:130 595 548,不管你是小白还是大牛都欢迎入驻 ,让我们一起进步,共同发展!(群内会免费提供一些群主收藏的免费学习书籍资料以及整理好的几百道面试题和答案文档!)

总结

这篇文章我们对iOS项目的启动入口进行了一次回顾和深入了解,相信你对iOS项目的发展有了一个更加清晰的认识。

感谢你的阅读💗。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容