前言
- 可以在Xcode中分析构建性能以加快构建速度。
- 为了研究构建性能,我们需要清除构建的缓存作为一个起始。这可以通过
Command + SHIFT + K或者Product ➔ Clean Build Folder...来清理
开始编译
- 编译之后我们可以通过如图,选择主工程的BuildLog并且打开Assistant查看编译的时间线
- 你可以通过双指放大缩小时间线,进而查看某个库的编译时间。当然也可以点击上方编译的Target,时间线会自动切换到该Target的Timeline
查看编译概览
也可以通过 Product ➔ Perform Action ➔ Build with Timing Summary查看编译时间概览
编译完成后,按照下图,选择Recent,滚动到最下面就能看到编译时间的概览
注意:我这里是一次增量构建。如果是全量构建,会有更多的信息可以查看
下面的图是一次全量构建的概览
可以看到CompileC花费了1112.13秒,而实际编译时间为235.418秒。这是因为整个构建系统是并发编译,CompileC是统计的编译源码的所有时间,所以看起来会比并发编译的时间长的多
构建阶段的优化
- 可以将一些在Debug下不需要运行的脚本忽略,让它只在Release下运行
- 可以使用 --quiet 静默编译,但该效果比较微弱
给编译器添加标记来统计单个表达式较长的耗时
-Xfrontend -warn-long-function-bodies=<limit>-Xfrontend -warn-long-expression-type-checking=<limit>
limit是一个毫秒数,如果表达式检查超过这个时间,编译器会发出警告
可以在build Settings中设置这些参数
Xcode15中Console的Options
可以通过 Command + SHIF + Y 或者 View → Debug Area → Show Debug Area打开Xcode底部的Console面板,然后按照下图可以查看Console的Options有哪些
- Type: 在每个log最前面的小图标
- Timestamp: log打印的时间戳
- Library: 在哪个库里打印的
- PID:TID: 进程以及线程id
- Subsystem: 使用logger的子系统,这个可以自己定义,一般使用自己的App名字就行
- Category: logger的分类,也可以自定义,大多数情况下每个模块是一个Category。比如网络、日志、数据库等 看个例子
过滤日志
可以通过底部的Filter来过滤日志。过滤的条件可以选择本类型以及非本类型
导航到log代码处
可以通过点击每条log右下角的向右箭头,直接导航到代码处
快速概览功能
还可以选中log,点击小眼睛,查看该条log的概览内容。在不打开Metadata Options时也依然有效
OSLog
OSLog是苹果推出的用于替代NSLog、print等方法的日志记录工具,它有更好的性能并且存储在设备上,在Mac上可以通过控制台程序读取
使用
使用时可以为Logger写一个扩展,针对每个模块功能创建一个单独的static属性
import OSLog
extension Logger {
/// Using your bundle identifier is a great way to ensure a unique identifier.
private static var subsystem = Bundle.main.bundleIdentifier!
/// Logs the view cycles like a view that appeared.
static let viewCycle = Logger(subsystem: subsystem, category: "viewcycle")
/// All logs related to tracking and analytics.
static let statistics = Logger(subsystem: subsystem, category: "statistics")
}
- Logger初始化时最好提供一个subsystem和category
- 创建后就可以使用里面各种level的日志输出方法
Logger可以怎么用?
- 可以使用字符串差值或字符串字面量输出日志,就和使用print一样
let username = "Example Username"
Logger.viewCycle.info("User \(username) logged in")
- 可以控制日志里部分字段的隐私
下面的代码对username使用了.private修饰,在控制台我们就看不到username了
Logger.viewCycle.info("User \(username, privacy: .private) logged in")
- 可以控制部分字段的对齐规则
Logger.statistics.debug("\(person.index) \(person.name, align: .left(columns: 10)) \(person.identifier)")
Logger.statistics.debug("\(person.index) \(person.name, align: .left(columns: Person.maxNameLength)) \(person.identifier) \(person.age, format: .fixed(precision: 2))")
Logger日志级别
- default (notice):默认的日志级别。最好通过使用其他日志级别来明确。
- info:调用这个函数来获取可能对故障排除有帮助但不是必需的信息。
- debug:在开发环境中主动调试时使用的调试级消息。
- trace:相当于调试方法。
- warning:用于报告意外的非致命故障的警告级别消息。
- error:用于报告严重错误和失败的错误级别消息。
- fault:故障级消息,仅用于捕获系统级或多进程错误。
- critical:功能等同于fault方法。
使用控制台查看日志
打开控制台,选择你的手机或者电脑,点击开始进行日志实时记录
开始记录后,可以在搜索栏搜索关键字,并且设置匹配条件进行过滤
甚至可以设置多个条件
同时设置可以搜索简介和调试信息