我正在为我们的应用程序实现遥测,我试图捕获的事情之一是 Apple 工程师在 WWDC 2019 的“优化应用程序启动”视频中描述的不同时间段。我很难准确捕捉第一帧和扩展阶段的时间。 我试图捕获它们,如下面的代码片段所示,并使用路标来表示记录点(每个
log..Started
和
log...Finished
。我所做的假设是:
在渲染第一帧之前调用 application:didFinishLaunchingWithOptions:
void PerformWhenIdle(dispatch_block_t block) {
CFRunLoopObserverCreateWithHandler(kCFAllocatorDefault,
kCFRunLoopAfterWaiting,
NO,
0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
block();
});
}
// ----------------------------
// AppDelegate.m
- (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[logger logFirstFrameRenderingStarted];
PerformWhenIdle(^{
[logger logFirstFrameRenderingFinished];
[logger logExtendedStageStarted];
});
}
// ----------------------------
// in TableVC.m
- (void)viewDidAppear {
[self.tableView reloadData];
PerformWhenIdle(^{
[logger logExtendedStageFinished];
});
}
当我检查仪器中的路标时,似乎第一帧的起点非常接近,但是第一帧似乎相当偏离,因此相比之下,扩展阶段似乎非常短,其中路标指示应用程序的持续时间为 225.23ms生命周期仪器显示花费了 1.78 毫秒:
我的假设不正确吗?如果是,是否说明仪器有问题?
application:didFinishLaunchingWithOptions: 方法确实在第一帧渲染之前被调用,但这并不是帧渲染开始时的最终决定。
当系统完成第一个绘制周期时,第一帧被视为已渲染。第一帧的持续时间应涵盖整个绘图周期,而不仅仅是立即回调。
void PerformWhenIdle(dispatch_block_t block) {
CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(kCFAllocatorDefault,
kCFRunLoopBeforeWaiting, // Changed to kCFRunLoopBeforeWaiting
NO,
0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
block();
CFRunLoopRemoveObserver(CFRunLoopGetMain(), observer, kCFRunLoopDefaultMode);
CFRelease(observer);
});
CFRunLoopAddObserver(CFRunLoopGetMain(), observer, kCFRunLoopDefaultMode);
}
// ----------------------------
// AppDelegate.m
- (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[logger logFirstFrameRenderingStarted];
PerformWhenIdle(^{
[logger logFirstFrameRenderingFinished];
[logger logExtendedStageStarted];
});
return YES; // Ensure you return YES from didFinishLaunchingWithOptions
}
// ----------------------------
// in TableVC.m
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self.tableView reloadData];
PerformWhenIdle(^{
[logger logExtendedStageFinished];
});
}
请尝试一下,如果有帮助请告诉我。