阅读视图

发现新文章,点击刷新页面。

Homebrew 5.0:并行加速、MCP 加持,与 Intel 的最后倒计时 - 肘子的 Swift 周报 #111

几天前,我像往常一样在输入 `brew update` 后顺手执行了 `brew upgrade`。出乎意料的是,终端里突然出现了从未见过的画面——大量组件与工具并行下载、整齐排列、同时推进。短暂的惊讶之后,我才从新闻中得知:Homebrew 已经发布了 5.0 版本

老司机 iOS 周报 #358 | 2025-11-17

ios-weekly
老司机 iOS 周报,只为你呈现有价值的信息。

你也可以为这个项目出一份力,如果发现有价值的信息、文章、工具等可以到 Issues 里提给我们,我们会尽快处理。记得写上推荐的理由哦。有建议和意见也欢迎到 Issues 提出。

新闻

objc4-950 源码更新

Runtime 的源码发布新版本,主要更新的是 Xcode26 的 objc_storeStrong 的逻辑,有兴趣可以自行查看。

App Store Mini App Partner Program 隆重推出

参与计划的开发者在销售符合条件的 App 内购买项目时,可享受 15% 的收益抽成减免。需要适配 Advanced Commerce API (ACA) 。微信已经发公告预计会进行接入,期待后续更多中国公司都能同样谈成优惠,让更多增值业务在 iOS 端上线。

文章

🌟 🐢 Optimize your app's speed and efficiency | Meet with Apple

@Smallfly:该视频围绕应用性能优化展开,结合苹果开发中心的实践场景,系统讲解了从 Swift UI 渲染到数据流管理的多维度优化策略。核心内容包括:

  • 工具与调试:通过 Xcode 实时观察界面渲染状态(黄色闪烁标记),使用功耗分析工具量化优化效果;推荐 Instruments 分析视图更新效率,明确性能瓶颈。
  • 技术实践:针对 Swift UI 提出减少视图更新的关键方法——避免存储闭包、初始化时预计算视图结果;利用 Observable 类优化数据流,降低卡片视图对状态变量的依赖。
  • 性能指标:强调监控启动时间、镜头应用延迟等关键指标,通过自动化测试发现问题;结合 Snap 的实践案例,说明团队协作与指标导向对维护应用健康的重要性。

视频通过代码演示与数据对比,为开发者提供了从工具使用到工程实践的全链路优化指南,特别提到 Liquid Glass 和 SwiftUI 的优化,推荐有兴趣的同学按需观看。

🐕 何时组建计算机性能工程团队(2025 年)第 1 部分(共 2 部分

@含笑饮砒霜:作者在文章中分享了非厂商性质技术密集型企业组建性能工程团队的核心建议,指出该团队能通过基础设施成本节约、延迟降低、可扩展性与可靠性提升、工程速度加快实现显著投资回报(如初期可减半基础设施成本,长期每年目标 5%-10% 成本节约),详细说明了性能工程师在新产品测试调优、内部工具开发、瓶颈分析、参数优化等十大核心职责,并给出组建时机与团队规模的参考规则(基础设施年支出超 100 万美元配 1 名工程师,后续每 1000-2000 万美元增 1 名;团队支出应不低于可观测性监测支出;延迟或可靠性阻碍增长时需组建),同时提及部分企业已有相关专职人员可纳入考量,后续第二部分将补充职位描述、潜在陷阱等内容。

🐕 TN3193: Managing the on-device foundation model’s context window

@JonyFang: Apple 在这篇技术说明中系统讲解了设备端基础模型的上下文窗口限制以及开发者应如何应对。文章强调:本地模型不会自动截断超长输入,超过窗口会直接报错,因此必须在应用设计中主动“预算”与管理上下文。Apple 建议使用三类策略来保持对话连续性同时不溢出窗口:

  • 滑动窗口:只保留最新内容,旧内容逐步丢弃;
  • 机会型摘要:上下文接近上限时触发自动总结,把详细内容压缩成短摘要继续对话;
  • 选择性保留 / 层级压缩:按重要性保留关键信息,把次要内容丢弃或按主题分层压缩,需要时再检索。

整体来看,TN3193 的核心信息是:Apple 设备端模型的上下文有限,开发者必须自行设计“记忆管理策略”,否则会遇到输入过长错误。通过“滑动 + 摘要 + 保留”组合策略,可在有限窗口内维持长对话与复杂任务的质量。

🐕 Demystifying AI Coding Agents in Swift

@Cooper Chen:这篇文章不仅手把手带你构建了一个可工作的 Swift AI Coding Agent,更重要的是,它用非常清晰、务实的方式揭开了 "AI 编码助理" 背后的底层原理。作者强调:这些看似强大的智能行为,其实都是从「语言模型 + 工具 + 循环」这三件极其简单的事组合而成,让人一下子从使用者变成真正理解者。

文章最大的价值在于 去魅 + 实操。它不讲虚的,不堆概念,而是用不到 300 行的 Swift 代码,就实现了一个能读文件、写代码、重构逻辑、与用户来回对话的 Coding Agent,让读者第一次意识到 Cursor、Claude Code 这类产品背后并没有不可思议的魔法。
与此同时,作者也展示了真实工程中会遇到的问题:上下文膨胀、循环保护、安全、错误处理、工具设计等,让内容不仅能“跑起来”,还具备工程实用性。

如果你想理解 Coding Agent 的本质,或者想自己打造一个轻量但功能完整的 Swift Agent,这篇文章绝对值得一读。它让复杂的概念变得透明,让看似神秘的 AI 能力真正变成可掌握、可自行构建的技术。

🐢 Roadmap for Improving the Type Checker

@AidenRao:你是否也曾被 the compiler is unable to type-check this expression in reasonable time 的错误困扰?Swift 编译器团队最近发布了一份详细的路线图,旨在系统性地解决这一由来已久的问题。文章深入浅出地解释了类型检查慢的根源——由类型推导和重载解析带来的指数级复杂度。
路线图不仅展示了近期 Swift 6.2 和 6.3 在编译速度上取得的显著成果(真实项目检查时间从 42 秒降至 10 秒),还规划了未来的改进方向:包括加速大型集合字面量检查、移除历史性能 Hack,乃至引入更先进的 SAT 求解技术。如果你对 Swift 编译性能的未来走向感兴趣,这篇文章值得一读。

🐎 来了解一下,为什么你的 Flutter WebView 在 iOS 26 上有点击问题?

@david-clang:iOS 26 上 WebView 点击失效,核心仍是 iOS 18.2 起 WKWebView 的手势状态缓存问题。

当 WebView 被 Flutter overlay 遮挡时,Flutter 通过 delayingGestureRecognizer 延迟 overlay 下方的 UIKit recognizer,使其暂时不触发,从而让 overlay 接管触摸。但 iOS 18.2 起 WKWebView 的手势状态缓存问题导致 overlay 消失后,WKWebView 内部的点击 recognizer 状态仍停留在延迟状态,未能恢复到 recognized,tap 或 JS click 无法派发,元素只能高亮却无法响应点击。

解决方案:

  • 短期规避:使用 pointer_interceptor 在 WebView 上方覆盖一个透明层,阻止 overlay 引发的手势中断,从而避免点击失效。
  • 长期方案:Flutter 官方正在弃用 delayingRecognizer,改为基于 hitTest + FFI 同步判断 的手势体系,在触点处直接判断是否应拦截手势,从根本解决 WebView、AdMob 等 PlatformView 的手势冲突问题。

代码

🐢 Swift Binary Parsing

@阿权:Apple 官方开源的二进制解析库,使用纯 Swift 编写,旨在构建安全、高效的二进制解析。该库提供了一系列用于安全解析二进制数据的工具,同时管理类型和内存安全,以消除常见的基于值的未定义行为,例如类型溢出。

Swift 一直致力于将不安全的内存操作尽可能安全地让用户访问、修改,此库跟 Swift 的思想如出一辙,本来之前 Apple 强推用 Swift 替代 C/C++ 直接操作内存,包括嵌入式也是这个切入点,此库一出如同如虎添翼了,也算是给内存操作提供一套完整的最佳实践了。

内推

重新开始更新「iOS 靠谱内推专题」,整理了最近明确在招人的岗位,供大家参考

具体信息请移步:https://www.yuque.com/iosalliance/article/bhutav 进行查看(如有招聘需求请联系 iTDriverr)

关注我们

我们是「老司机技术周报」,一个持续追求精品 iOS 内容的技术公众号,欢迎关注。

关注有礼,关注【老司机技术周报】,回复「2024」,领取 2024 及往年内参

同时也支持了 RSS 订阅:https://github.com/SwiftOldDriver/iOS-Weekly/releases.atom

说明

🚧 表示需某工具,🌟 表示编辑推荐

预计阅读时间:🐎 很快就能读完(1 - 10 mins);🐕 中等 (10 - 20 mins);🐢 慢(20+ mins)

iOS 社招 - Runtime 相关知识点

核心概念 本质:runtime是 oc 的一个运行时库(libobjc.A,dylib),它为 oc 添加了 面向对象的能力 以及 运行时的动态特性。 面向对象的能力:rutime用 C 语言实现了类

Vibe Coding 实战!花了两天时间,让 AI 写了一个富文本渲染引擎!

一、先上效果图

最近动手实践了下 Vibe Coding,想尝试一行代码不写,纯通过 Prompt 让 AI 写了一个富文本渲染引擎

整体花了两天时间不到,效果如上图,支持的特性有:

  • 类似前端的 Block、InlineBlock、Inline 布局
  • 文本样式:加粗、斜体、下划线、删除线,前景色,背景色,同一行不同字体大小混排等
  • Attachment:图文混排或插入自定义 View 等
  • 异步排版和算高:基于 CoreText API,支持子线程布局算高,主线程渲染
  • 单测覆盖

项目用的 Claude AI,差不多耗费了 50$(是真的贵!但也是真的强!),本文将记录整个过程和一些经验总结。

二、过程记录

2.1 Claude 安装和项目初始化

Claude 安装和使用在网上有很多教程,细节这里不再赘述,推荐直接使用 VSCode 的 Claude AI 插件;后文「经验总结」部分也会总结 Claude AI 的常用命令,感兴趣可以直接跳转。

首先,我们需要新建一个空的 iOS 项目和富文本渲染引擎的 pod(这里我们叫 RichView),创建完成之后在 VSCode 中打开,点击右上角 Claude AI 的图标开启会话,输入/init 命令初始化工程。

/init命令的作用是让 Claude 理解整个项目,这是在项目中使用 Claude 的第一步,只需要执行一次就好。

/init会在根目录下自动创建一个CLAUDE.md文件,这个文件可以理解成全局上下文,即每次新开 Claude 会话都会自动加载其中的内容,我们可以在这里记录一些如修改历史、全局说明等内容。

2.2 技术选型、架构

让 AI 写代码,和我们自己写代码基本类似,不过是将我们的思路转换成 Prompt 告诉 AI。

编码之前需要先确定几件事情:这些确定好之后,我们后续的任务拆分才会更顺利。

1)需要支持哪些 Feature

  • 支持文本样式:加粗、斜体、下划线、删除线,前景色,背景色,同一行不同字体大小混排等
  • 支持 Attachment:图文混排或插入自定义 View 等
  • 支持子线程排版算高
  • 支持单元测试

2)技术选型

自定义富文本渲染引擎,最难的点在于如何实现精确的文本分词排版(原理可以参考从 0 到 1 自定义文字排版引擎:原理篇),iOS 有内置的 CoreText API(见链接)用于文本分词排版,当然也可以基于开源的跨端排版引擎 HarfBuzz(见链接)进行处理。

我们这里不需要跨端,因此选择 CoreText 作为方案选型。

官方封装的 NSAttributedString 当然也能做这件事情,但是从工程实践看,NSAttributedString 在扩展性(比如支持列表、表格等自定义布局)、使用方便性,以及长文本的性能方面不尽如人意。

3)技术架构

文本分词之后,还需要进行布局排版,为方便后续拓展布局,我们这里参考前端的布局模型,引入 Block、InlineBlock、Inline 的概念。

同时参考浏览器的布局渲染过程,引入三棵树的概念:

  • ElementTree:用户输入,整个富文本可以通过一颗 ElementTree 来表示
  • LayoutTree:负责布局排版,会在这一层处理好文本的分词、图文混排时各自的位置等
  • RenderTree:负责渲染,这一层接收布局完成的结果,进行最终的上屏绘制

敲定技术选型、技术架构之后,我们就可以按思路拆分子任务了。

2.3 子任务:ElementTree

由于我们参考了前端的布局模型,因此我们需要告诉 AI 在 CSS 中 Block、InlineBlock、Inline 的布局规范,这个在 MDN 中可以直接摘录,当然也可以直接让 AI 帮我们生成(如上图)。

接着,我们需要告诉 AI 怎么构建 ElementTree,也就是上图所示 Prompt。

最后,我们就可以让 AI 参照 Prompt,生成 ElementTree 了。

ElementTree 生成完成后,我们发现遗漏了单测环节,继续完善 ElementTree 的 Prompt,然后明确告诉 AI xx 文件新增了 xx 任务,让 AI 继续完成任务,如下图:

ElementTree 的创建还算比较顺利,AI 理解也比较到位,生成的代码基本符合预期。

2.4 子任务:LayoutTree

同样,我们定义好 Prompt,让 AI 生成 LayoutTree。

LayoutTree 的生成不太顺利,而且从最后的测试效果看也有很多 Bug,主要如下:

  • AI 将绘制相关逻辑也加到了 LayoutTree 中,但预期绘制是单独的 RenderTree
  • 布局问题:InlineBlock 无法整体换行,多个 Inline 在同一行时被换行展示,margin、padding 不生效等
  • 对齐问题:同一行包含不同字号的文本时,对齐方式不对
  • attachment 无法显示

2.5 子任务:RenderTree

由于 LayoutTree 这个底层基础没扎实,RenderTree 的搭建也不顺利,RenderTree 的 Prompt 如上。

2.6 BugFix

至此,AI 生成了初版的富文本渲染引擎,接下来就是让 AI 写个 Demo 试用一下,在使用过程中,发现了很多上面罗列的 Bug,针对这些 Bug,也可以让 AI 来修复:

在让 AI 修 Bug 过程中,也踩了一些坑,参见下文经验总结。

三、一些经验总结

3.1 Claude AI 常用命令

  • /init:项目初始化,第一次使用 Claude AI 时执行,每个项目只需要执行一次即可;会生成一个CLAUDE.md文件,这是项目的全局上下文,每次新建 Claude 会话时,会自动读取其中的内容;可以在CLAUDE.md文件中补充修改历史、全局说明等
  • @:可以输入@来添加文件到会话窗口,将文件作为上下文给 AI
  • /exit:关闭当前会话
  • /clear:清除当前会话上下文,和退出会话然后新开一个会话效果一样
  • /compact:压缩和总结当前会话上下文,和/clear的区别是,/compact会将当前会话上下文总结后作为当前会话的新上下文,/clear会直接清除所有上下文
  • /resume:显示和恢复历史上下文
  • 自定义 command:可以将通用的 Prompt 做成自定义 command,文件位置在.claude/commands/;还可以通过 $ARGUMENUTS 来接收自定义参数

  • /agents:有的任务比较复杂,或上下文较多,那可以拆分成多个 agents 进行组合,比如写业务逻辑 -> 构建单元测试 -> CI/CD 等,可以拆分多个 agents 组合使用

  • 会话模式:在最新版本的 Claude AI 插件中,除了之前命令行风格的 GUI 以外,还提供了会话框风格的 GUI,切换会话模式,查看历史会话等会更方便;如下,会话模式可以在输入框左下角切换

    • Edit automatically:AI 根据输入 Prompt 进行理解并直接编辑文件,一般使用该模式即可

    • Plan mode:AI 根据输入 Prompt 列出修改计划,你可以进一步校验和修改 Plan

    • Ask before edits:AI 修改文件前询问

  • MCP:常用的 MCP 是context7context7是用于帮助 AI 查找最新文档的,避免使用过时 API

3.2 经验总结

不得不感叹,AI 编程实在太强大了,相信在不久的将来,一个只会写 Prompt 的非专业程序员,也能完整交付一个 App 了。

让 AI 编程,并不是说给一句话就能让 AI 完成代码,各种细节还是需要人来提前想清楚,毕竟最终维护代码和解决问题的还是我们自己,AI 只是帮我们提效和扩展思路的工具;有句话总结的蛮好:你可以将 AI 视为一个非常聪明,甚至资深,但是没有业务经验的程序员。

下面我想总结下最近实战的一些经验,希望对各位有帮助:

1)架构设计需要提前规划好,尽量想清楚细节

谋定而后动,不管是我们自己写代码,还是让 AI 写代码,我觉得提前想好要做什么,怎么做是非常重要的。

架构设计好了,细节想清楚了,那怎么拆分子任务,其实也就明确了。

2)任务拆分越小越好,上下文越明确越好

AI 最适合做有明确输入输出的事情,给的上下文越明确,AI 产生幻觉的概率越低,输出结果也会越准确。

当然,如果是输入输出明确的任务,也可以让 AI 先输出测试用例,测试用例人工检测完备之后,再让 AI 编码也是可以的(测试驱动开发/TDD)。

3)每一项目任务做好之后再进行下一项任务

基础不牢,地动山摇!

推荐打磨好每一项子任务再继续下一项任务,否则千里之堤毁于蚁穴,每个任务都留一点坑,最终可能带来灾难性的结果!

另外,单测是个好东西,对每项任务补齐单测,可以有效防止后续 AI 改出问题。

4)善用 Git,防止代码污染

Claude 在 Edit automatically 模式下会直接修改文件,为了防止污染其他代码,每次让 AI 修改前尽量保证工作区干净,这样也能方便我们 Review 代码。

5)写 Prompt 尽量用明确的词汇,不要表意不清

比如在构建 ElementTree 时,我会明确告诉 AI 要支持哪些 Style,可以有效避免 AI 臆测

与之相反的反例是,在构建 LayoutTree 时,限定不足,导致 AI 自由发挥,最终实现出很多 Bug。

6)善用提示词:think < think hard < think harder < ultrathink

可以在 Prompt 中追加 think hard / think harder 等词汇,来让 AI 进入深度思考,这并不是什么黑魔法,而是 Claude AI 官方认证的,参见:www.anthropic.com/engineering…

实践下来,确实还是有效果的,如下是让 AI 修复文本对齐问题,加了 think hard AI 会更深入理解代码,找到问题原因;当然,这种方式也有弊端,就是会耗费更多的 token(money)👺

7)善用 /compact /clear命令,减少模型幻觉

如果不主动清除,Claude AI 会话中的上下文是会一直保存的,当一个会话中问答轮次过多,可能会导致 AI 理解不准确(幻觉)。

可以通过/compact/clear命令,来压缩/清除上下文。

一般我在修复有关联性的 Bug 时,会使用/compact命令,这样 AI 就不需要重新理解工程,理解 Bug 了,可以提高效率。

8)BugFix 尽量构造最小可复现 Demo

BugFix 其实也是一个子任务,最小可复现 Demo 减少 AI 的理解负担。

9)及时人工介入,避免在一个问题上死磕

有时候让 AI 修复 Bug 时,可能反复修改都解决不了,这时候大概率是 AI 没有真正理解问题,或者就是输入的 Prompt 有问题,这种情况下就没必要让 AI 死磕问题了,我们可以及时人工介入,避免浪费时间。

10)善用 Plan 模式

在任务拆分时,我们自己可能也没想明白应该怎么做,那可以切换到 Plan 模式,让 AI 和我们一起拆任务。

3.3 Vibe Coding 的一些弊端

1)付费,而且还挺贵!

这是一个挺现实的问题,一些好的模型都挺贵,而且还是消耗的刀乐,国内厂商的模型质量又不尽如人意。

2)编码风格问题 & 扩展性、易用性、鲁棒性不足

AI 写的代码还是挺容易看出来的,感觉很难带有程序员的个人风格,一个明显的表现是会用一些比较少见的 API,虽然,这可能也是 AI 的厉害之处。

另外,AI 在一些函数复用性、扩展性、使用方便性上有时候差强人意,比如 AI 生成代码如下:如果要配置 Element 的 Style,需要不断的调用text.style.xxx,但其实写成链式调用使用起来会更舒服,如下注释部分

let text = TextElement(text: "一、晨光初照")
text.style.color = .red
text.style.font = UIFont.systemFont(ofSize: 17)

// 更好的写法
// text.style.setColor(xxx).setFont(xxx)

鲁棒性方面,AI 不会主动考虑调用场景,比如我虽然告诉了 AI 我要支持子线程布局,但是 AI 生成的代码并不是线程安全的。

当然,上述这些,可以通过完善 Prompt 来部分弥补。

3)问题定位幻觉

有时候让 AI 排查一些 Bug,它无法找到真正的原因,反复修改后还是有问题。

这种情况下,就需要人工介入了,我们可以自己定位问题,再告诉 AI 怎么修改,而不要让 AI 死磕问题,避免浪费时间。

四、贴下源码 & Prompt

github.com/HusterYP/Ri…

内容首发在公众号「非专业程序员Ping」,觉得有用的话,三连再走吧~ (⁎˃ᴗ˂⁎)
富文本相关,你可能感兴趣:

❌