发布时间:2026/8/12 18:15:37
instruments 之 points of interest 使用 Points of Interest 是什么Instruments 中的Points of InterestPOI关注点可以理解为由你主动埋在代码里的“性能时间标记”。Instruments 本身能够告诉你 CPU、内存、线程在什么时候繁忙但它并不知道那一刻你的 App 正在执行什么业务操作。通过 POI你可以在时间轴上标记用户点击了“发送消息”首页开始加载图片解码开始和结束列表首屏渲染完成页面切换开始和结束这样就可以把业务行为和 CPU、卡顿、网络、线程活动对应起来。POI 并不是一种新的底层采集机制它本质上使用的是OS Signpost。当 Signpost 被写入.pointsOfInterest分类时Instruments 会把它突出显示在 Points of Interest 轨道中。Apple 目前推荐使用OSSignposterAPI。(Apple Developer)因些Points of Interest 本身不负责发现性能问题但它能显著提高分析效率。两种标记类型1. Event一个瞬间表示某件事情在某个时刻发生了没有持续时间。例如signposter.emitEvent(User Tapped Send)在 Instruments 时间轴上它表现为一个时间点。适合用户点击按钮页面出现收到推送开始一次刷新缓存命中网络请求失败emitEvent的含义就是“在当前时刻记录一个关注点”。(Apple Developer)2. Interval一段持续时间表示一项工作从什么时候开始到什么时候结束。图片解码开始 ├──────────────┤ 图片解码结束适合页面加载JSON 解析图片解码数据库查询网络请求列表布局动画执行App 启动后的初始化工作Apple 的OSSignposter通过beginInterval和endInterval创建区间Instruments 会把它显示成一段可选择的时间范围。(Apple Developer)iOS 15 以上使用 OSSignposter1. 创建统一的 Signposterimport os enum AppSignpost { static let signposter OSSignposter( subsystem: Bundle.main.bundleIdentifier ?? com.example.app, category: .pointsOfInterest ) }这里有两个关键参数subsystem通常使用 App 的 Bundle IDcategory使用.pointsOfInterest.pointsOfInterest是系统专门用于 Signpost 和 Instruments POI 轨道的分类。(Apple Developer)2. 标记一个瞬间事件例如记录用户点击发送按钮func sendButtonDidTap() { AppSignpost.signposter.emitEvent(Send Button Tapped) sendMessage() }或者加入一些附加信息func sendButtonDidTap(conversationID: Int) { AppSignpost.signposter.emitEvent( Send Button Tapped, conversationID: \(conversationID) ) sendMessage() }第一个字符串Send Button Tapped必须是静态字符串动态数据应该放在后面的 metadata 中。OSSignposter支持在 metadata 中使用字符串插值以及隐私选项。(Apple Developer)3. 测量一段同步代码例如测量 JSON 解析func parseResponse(_ data: Data) throws - Response { let state AppSignpost.signposter.beginInterval( Parse Response, dataSize: \(data.count) ) defer { AppSignpost.signposter.endInterval( Parse Response, state ) } return try JSONDecoder().decode(Response.self, from: data) }使用defer很重要因为无论方法正常返回还是抛出错误都能保证 interval 被结束。在 Instruments 中会看到Parse Response ├──────── 18 ms ────────┤4. 使用 withIntervalSignpost对于同步闭包写法可以更简单func parseResponse(_ data: Data) throws - Response { try AppSignpost.signposter.withIntervalSignpost( Parse Response, dataSize: \(data.count) ) { try JSONDecoder().decode(Response.self, from: data) } }withIntervalSignpost会自动包围闭包负责开始和结束 interval特别适合短小、同步的测量代码。(Apple Developer)5. 测量 async 任务func loadUserProfile(userID: Int) async throws - UserProfile { let signpostID AppSignpost.signposter.makeSignpostID() let state AppSignpost.signposter.beginInterval( Load User Profile, id: signpostID, userID: \(userID) ) defer { AppSignpost.signposter.endInterval( Load User Profile, state ) } let data try await apiClient.requestUser(userID: userID) return try JSONDecoder().decode(UserProfile.self, from: data) }这里显式创建了signpostID。当同名任务可能并发执行时例如同时下载多张图片、加载多个用户资料需要为每个任务生成不同 ID。否则 Instruments 无法正确区分每一对开始和结束标记。只有在同名 interval 绝不可能重叠时才适合使用默认的.exclusive。(Apple Developer)几个容易踩的坑1. begin 和 end 名称必须一致let state signposter.beginInterval(Load Messages) // 错误 signposter.endInterval(Load Message, state)在 Debug 构建中OSSignposter会检查名称、状态和对应的 Signposter 是否一致不匹配可能触发运行时断言。(Apple Developer)2. 同名并发任务不要都使用默认 ID多个并发图片下载都叫Download Image时应使用let id signposter.makeSignpostID()而不是全部依赖.exclusive。(Apple Developer)3. Signpost 名称不能使用普通动态字符串下面不能直接使用let name Load \(pageName) signposter.beginInterval(name)因为 name 要求是StaticString。应改成signposter.beginInterval( Load Page, pageName: \(pageName) )4. 可以在 Release 中关闭需要完全关闭时可以使用#if DEBUG static let signposter OSSignposter( subsystem: Bundle.main.bundleIdentifier ?? com.example.app, category: .pointsOfInterest ) #else static let signposter OSSignposter.disabled #endifApple 提供了OSSignposter.disabled用于在生产构建中关闭 Signpost而不必修改调用代码。(Apple Developer)最简单的心智模型Instruments 指标 告诉你系统什么时候忙。 Points of Interest 告诉 Instruments那时候你的 App 正在做什么。 Event 某件事发生了。 Interval 某件事执行了多长时间。

相关新闻

2026/8/12 18:15:37

代码库知识库系列(13):评测——怎么知道知识库够不够好

为什么 Recall@5 不够用 第03篇开了一个先例:用 30 道检索题测向量路径,Recall@5 = 0.958。后来每篇涉及检索实验的文章,都用类似的方式汇报结果。 Recall@5 是个合理的起点指标,但它有三个盲区: 盲区一:精度。 Recall@5 问的是"正确答案有没有出现在前5个结果里…

2026/8/12 18:10:37

揭秘僵尸进程:父进程为何必须等待子进程

进程等待进程等待必要性(为什么)之前讲过,子进程退出,父进程如果不管不顾,就会造成僵尸进程的问题,进而造成内存泄漏。另外,进程一旦变成僵尸进程(进程停止运行,不被CPU调…

2026/8/12 19:15:42

RAG 系统如何利用元数据过滤提升检索精度?

RAG 系统如何利用元数据过滤提升检索精度? RAG 系统如何利用元数据过滤提升检索精度? 在 RAG(检索增强生成)系统中,元数据过滤(Metadata Filtering)是一种在向量检索之前或期间,根据…

2026/8/12 19:15:42

3D模型局部变形技术:从顶点操作到面部网格塑形实战

大家好,我是专注于技术分享的博主。今天我们来聊聊一个在计算机图形学、游戏开发和3D建模领域非常核心的概念—— 面部网格变形与顶点操作 。听起来有点抽象?别急,我们可以用一个非常形象的比喻来理解:就像医美领域的“鼻基底填…

2026/8/12 19:15:42

Debian系统开机自启动配置全解析:从SysVinit到systemd实战指南

1. 项目概述:为什么开机启动是运维的必修课在Debian服务器或桌面环境的日常运维中,让特定的命令或脚本在系统启动时自动运行,是一个看似基础却至关重要的技能。无论是部署一个Web服务、启动一个数据库守护进程,还是简单地挂载一个…

2026/8/12 19:15:42

STM32 GPIO模拟DVP接口驱动OV2640摄像头实战指南

1. 项目缘起:当标准接口遇上“非标”需求最近在做一个基于STM32F1的嵌入式图像采集项目,核心需求是驱动一颗OV2640摄像头模块。OV2640这颗200万像素的CMOS传感器,在消费电子和工控领域应用很广,性价比不错。它通常通过DVP&#xf…

2026/8/12 19:15:42

RAG 系统在生产环境中如何优化性能和降低成本?

RAG 系统在生产环境中如何优化性能和降低成本? RAG 系统在生产环境中如何优化性能和降低成本? 生产环境中的 RAG 系统,挑战已不再是“能不能做”,而是“如何在有限成本下,稳定、高效地输出高质量结果”。优化需要同时关…

2026/8/12 19:10:42

循环工程:构建自适应系统的核心思维与四要素实践

1. 从“循环”到“工程”:一个被低估的思维范式如果你在技术社区、产品讨论或者项目管理会议上,听到“Loop Engineering”这个词,第一反应是不是有点懵?它听起来像是一个具体的编程技巧,或者某个小众的框架。但今天我想…

2026/8/12 10:37:12

如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南 【免费下载链接】chinese_license_plate_generator 中国车牌生成器 项目地址: https://gitcode.com/gh_mirrors/ch/chinese_license_plate_generator 中国车牌生成器是一个基于Python的开源项目&#xff0c…

2026/8/12 5:35:25

当 LLM 遇见大文档:主流开源项目如何处理上下文超限

从 Agentic Loop 到 Repo Map,七种策略与六类陷阱引言:128K vs 10MB 的硬冲突 2026 年的 LLM 上下文窗口已达到 128K ~ 1M token(≈ 0.5MB ~ 4MB 文本),但 LLM 想要处理的真实数据规模远远超过这个量级:真实…

2026/8/12 9:34:08

Ubuntu 23.10中双击运行.sh文件的完整指南:从权限原理到桌面配置

1. 项目概述:从一次“双击”引发的权限探索在Ubuntu桌面环境下,我们习惯了双击运行那些带有.exe后缀的Windows程序安装包,但当你拿到一个以.sh结尾的Shell脚本文件时,满怀期待地双击它,却很可能只看到一个文本编辑器窗…

2026/8/12 9:34:08

NumPy条件索引实战:np.where与np.argwhere高效数据筛选指南

1. 从一次数据筛选的“笨办法”说起 前几天,我帮一个刚入行的数据分析师同事看代码,他正在处理一批传感器数据,需要找出所有温度超过阈值的数据点,然后进行后续分析。我一看他的实现,好家伙,一个 for 循环…

2026/8/12 9:34:08

基于Docker与Selenium Grid构建高可用浏览器自动化测试环境

1. 项目概述:为什么需要容器化的浏览器自动化?在软件开发和测试领域,浏览器自动化早已不是新鲜事。无论是日常的UI回归测试、数据抓取,还是复杂的业务流程模拟,Selenium都是我们绕不开的利器。然而,但凡在团…

2026/8/10 11:20:30

实测才敢推 AI论文网站 2026最新测评与推荐

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。一、综…

2026/8/11 17:06:59

2026必备!AI论文网站测评:最新推荐与深度对比

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

2026/8/11 3:05:11

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…