iOS 15 的意外启动时间

Unexpected launch time on iOS 15

我注意到应用程序在iOS 15 启动时出现一些奇怪的报告。我使用以下代码方法来获取进程创建时间,

NSInteger rm_task_create_time(void) {
    static dispatch_once_t onceToken;
    static NSInteger taskCreateTimeMs = 0;
    dispatch_once(&onceToken, ^{
        struct kinfo_proc kProcInfo;
        if (rm_process_info([[NSProcessInfo processInfo] processIdentifier], &kProcInfo)) {
            taskCreateTimeMs = kProcInfo.kp_proc.p_starttime.tv_sec * 1000 + kProcInfo.kp_proc.p_starttime.tv_usec * 1.0E-3;
        }
    });
    return taskCreateTimeMs;
}

使用以下代码获取app的第一个runloop执行时间作为第一帧渲染时间,

static NSInteger firstDrawTime;
- (void)startFirstDrawMonitor:(void(^)(void))completeHandler {
    CFRunLoopRef mainRunloop = [[NSRunLoop mainRunLoop] getCFRunLoop];
    CFRunLoopActivity activities = kCFRunLoopAllActivities;
    CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(
        kCFAllocatorDefault, activities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
            if (activity == kCFRunLoopBeforeTimers) {
                firstDrawTime = [NSDate date].timeIntervalSince1970 * 1E3;

                CFRunLoopRemoveObserver(mainRunloop, observer, kCFRunLoopCommonModes);
                CFRelease(observer);
            }
        });
    CFRunLoopAddObserver(mainRunloop, observer, kCFRunLoopCommonModes);
}

然后使用“firstDrawTime - rm_task_create_time()”来计算应用程序的启动时间。 但是从我们得到的数据来看,冷启动时间有很多异常值,比如31405290ms、8310805ms、5177209ms,但是从didFinishLaunch到第一次runloop执行的时间是合理的,只有几百毫秒。 ios15之前没有这个问题。所以我推测在iOS15上可能有一些路径会导致进程启动时没有调用didFinishLaunch,或者其他一些可能。那么谁能告诉我 iOS15 中的哪些更改会影响启动时间?或者任何其他可能导致此问题的更改?谢谢。

我发现这是 ios15 的新功能 prewarming

在 iOS15 及更高版本中,系统可能会根据设备条件预热您的应用程序 - 启动非运行的应用程序进程以减少用户在应用程序可用之前等待的时间。预热会执行应用程序的启动序列,直到但不包括 main() 调用 UIApplicationMain(::::) 时。这为系统提供了构建和缓存它在预期全面启动时所需的任何低级结构的机会。

您可以阅读此文档。 about_the_app_launch_sequence