当每一次写入都有了新价格 -- 肘子的 Swift 周报 #144
当每一次写入都有了新价格最近OpenAI 的 Codex 被发现存在一个日志写入问题程序会持续向本地数据库写入大量日志导致文件不断膨胀并产生远超正常水平的磁盘写入。类似的 Bug 过去并不少见。放在几年前人们大概只是删除文件、重启应用然后等待下一个版本修复。但这一次大家的反应明显不同。比起“还剩多少磁盘空间”更多人开始关心 SSD 已经累计写入了多少数据会不会影响闪存寿命以及未来更换设备时需要为同样容量的内存和存储多付多少钱。Codex 的 Bug 未必比过去那些失控的日志程序更加严重。真正发生变化的是每一次无意义的写入似乎都重新有了价格。随着 AI 算力需求迅速增长存储器厂商越来越倾向于优先保障 HBM、服务器内存和企业级 SSD 等利润更高、需求更旺盛的产品。消费级内存和 SSD 能够分配到的产能因此受到挤压价格也不断走高。内存和闪存本来就是典型的周期性行业价格上涨和下跌并不罕见。但这一轮变化令人不安的地方在于它似乎不再只是一次简单的库存周期而是伴随着产业资源向 AI 基础设施长期倾斜。即使价格最终仍会回落消费者恐怕也很难迅速回到过去那种“大容量近乎免费”的心理预期。当存储不再显得取之不尽时开发者或许也应该转变对资源时的态度。在我最开始接触电脑时Apple II 常见的内存配置只有 48 KB。为了使用扩展卡额外提供的 16 KB 空间开发者需要仔细安排地址、代码和数据想方设法把每一个字节都利用起来。今天一个数十 GB 的游戏必然拥有 FC 时代无法想象的画面、声音、世界规模和交互复杂度。然而巨大的容量并不能保证它带来的乐趣一定超过一个只有几十 KB 的游戏。这并不是说现代软件不应该变大。真正值得思考的是在过去很多年中开发者已经习惯了存储容量会自然增长、网络会不断变快。日志、缓存和临时数据只要暂时还放得下就很少有人追问它们为什么存在又将在什么时候被删除。昂贵的 SSD 不会自动创造优秀的软件内存短缺也不会让开发者突然变得更加聪明。但当硬件不再被默认会无限增长时那些曾经被忽视的工程问题便会重新浮出水面。我并不怀念那个需要在几十 KB 中反复腾挪的时代。真正值得重新拾起的并不是资源匮乏而是那种曾经十分自然、后来却逐渐消失的工程习惯知道每一个字节为什么到来也知道它将在什么时候离开。本期内容 | 前一期内容 | 全部周报列表近期推荐iOS 设备锁定后Swift Task 能运行多久(Swift Task lifetime when an iOS device is locked)这是一篇来自 Apple Developer Forums 的问答。提问者发现一个会串行执行多个 REST 请求的 Swift Task在设备锁定后有时能够正常完成有时会暂停甚至出现超时。DTS 工程师 Quinn “The Eskimo!” 解释道Swift Concurrency 完全运行在应用进程中一旦 iOS 挂起进程执行 Task 的工作线程也会停止Task 本身并不会获得额外的后台运行能力。这种机制在网络请求中尤其容易造成困惑。应用被挂起时正在进行的 URLSession 请求可能因连接失效而失败进程恢复后开发者看到的可能是请求超时或网络错误而不是 Task 从暂停处继续并顺利完成。Quinn 给出了四种处理方向设法延缓进程挂起、在应用即将被挂起时停止请求、允许请求失败并做好重试与错误恢复或者使用 URLSession 的后台会话。Swift 6.4 中的 anyAppleOS (anyAppleOS in Swift 6.4)过去为跨 Apple 平台共享的 API 声明可用性时开发者需要分别列出各个平台及其对应的系统版本。由于不同平台的版本号长期不一致这类声明不仅冗长也容易出现遗漏或版本填写错误。随着 Apple 各平台从 26 开始统一版本号Swift 6.4 引入了anyAppleOS允许开发者在available、#available和#if os(...)中以更简洁的方式描述适用于 Apple 操作系统的 API 与代码。Artem Mirzabekian⁠ 介绍了这一新语法并梳理了它与平台专属可用性、canImport以及Package.swift平台声明之间的区别同时说明了如何结合更具体的可用性规则处理部分平台延后支持或完全不可用的情况。可复用 SwiftUI 视图的设计剖析 (The Anatomy of a Reusable SwiftUI View)越来越多的开发者在构建可复用 SwiftUI 视图时都希望其 API 尽可能贴近 Apple 官方的设计方式但具体如何落地往往缺少一套清晰的方法。Alexander Weiß⁠ 给出了自己的设计思路首先判断组件属于描述功能概念的语义型组件还是具有明确视觉形态的规定型组件再梳理其语义、合法状态、数据流与交互行为。同时组件还应遵循 SwiftUI 的状态管理方式正确使用不可变值、Binding 与 State并将无障碍支持、环境值和视图身份稳定性纳入设计而不只是关注 API 的调用形式。文章通过 Card、Tag 和 Rating 三个示例展示了初始化方法、自定义 View Style 和环境值等具体实现。这套方法的核心并非简单模仿 Apple API 的外形而是让自定义组件在组合方式、状态流转、交互行为、无障碍支持和环境适配等方面真正融入 SwiftUI 体系。SwiftUI 环境默认值不稳定的隐性成本 (The hidden cost of unstable SwiftUI environment defaults)Entry宏让自定义环境值的声明更加便捷但如果直接将引用类型实例作为默认值例如Entry var logger AppLogger()就可能带来不必要的视图更新。每当 SwiftUI 没有找到上层注入的值而回退到默认值时都可能重新创建一个AppLogger。这些对象虽然功能相同却不是同一个实例因此 SwiftUI 会认为环境值发生了变化进而重新计算读取它的视图。Xcode 27 开始会针对这种写法发出警告让这个过去不易察觉的问题更早暴露出来。Natalia Panferova⁠ 使用_printChanges()直观展示了这一问题并给出两种解决方式将默认实例保存在稳定的外部存储中或者将环境值声明为 Optional再由应用入口显式注入。我在《SwiftUI Environment理念与实践》中也分析过这一问题。其根源在于Entry宏生成默认环境值的方式使默认表达式可能在回退访问时被重复求值。使用 visualEffect 为 SwiftUI ScrollView 创建纵向视差效果 (Make Vertical Parallax for ScrollView in SwiftUI)早期的二维游戏通过让不同图层以不同速度移动用很低的成本便营造出了富有层次感的视觉效果。但在 SwiftUI 中实现滚动视差真正麻烦的通常不是计算偏移量而是持续获取每个视图在ScrollView中的位置。过去这类效果往往需要结合GeometryReader、自定义坐标空间和状态传递来完成不仅代码量较大处理不当还可能引发额外的视图更新。visualEffect的引入大幅降低了这类效果的实现难度。codelaby⁠ 展示了如何直接在visualEffect中读取视图的几何信息并根据滚动位置应用offset无须额外维护状态也不会改变视图原有的布局。工具swift-span-algorithms: 给 Span 补上算法能力在处理连续内存时Swift 过去主要有两类选择使用Array、ContiguousArray等拥有存储的容器安全易用但可能伴随复制、引用计数或额外分配使用UnsafeBufferPointer等指针类型成本低、控制力强却需要开发者自行保证内存仍然有效并避免越界访问。Swift 6.2 新增的SpanElement填补了两者之间的空白。它是一段连续内存的非拥有视图不持有底层存储却能借助编译器追踪生命周期并通过边界检查提供安全访问。不过在 Swift 6.2 中Span 尚未拥有 Collection、Sequence 那般完整的算法能力。David Retegan 开发的 swift-span-algorithms 正是对这一缺口的补充。它为 Span、RawSpan、MutableSpan 和 InlineArray 提供查找、比较、修剪、分块、滑动窗口、切分及游标Cursor等操作。整个库零以无隐藏分配和常数级额外空间为设计目标在扩展算法能力的同时仍然遵守 Span 的生命周期约束。往期内容当 Linux 成为“空气”容器、Agent 与不再重要的“桌面之争” - #143SPI 加入 AppleSwift 迈向自举 - #142Swift 还让你 Excited 吗- #141WWDC 26AI 帮你看完了然后呢- #140 支持与反馈如果本期周报对你有帮助请点赞- 让更多开发者看到评论- 分享你的看法或问题转发- 帮助同行共同成长拓展 Swift 视野 邮件订阅| weekly.fatbobman.com 获取独家技术洞察 开发者社区| Discord 实时交流开发经验 原创教程| fatbobman.com 学习 Swift/SwiftUI 最佳实践

相关新闻

SAP UI5 里最接近 Angular OnInit 的机制,Controller onInit 与生命周期边界

SAP UI5 里最接近 Angular OnInit 的机制,Controller onInit 与生命周期边界

答案可以直接落在一个方法上,SAP UI5 的 Controller.onInit 就是最接近 Angular OnInit 和 ngOnInit 的技术。两边都把一段初始化逻辑交给框架,在对象进入可工作状态的特定时刻自动执行,业务代码只需要实现约定的方法,不需要手工调用。不过,名称相似不等于语义完全一致。A…

2026/7/15 4:21:52阅读更多 →
Unity URP升级:解决材质变粉红的三种实战方案

Unity URP升级:解决材质变粉红的三种实战方案

1. 项目概述:从内置管线到URP的材质“粉红危机”如果你正在将Unity项目从内置渲染管线(Built-in Render Pipeline)升级到通用渲染管线(Universal Render Pipeline,简称URP),并且发现场景里的模型…

2026/7/15 4:21:52阅读更多 →
AI 眼镜多模型对比 Agent 技术文档

AI 眼镜多模型对比 Agent 技术文档

1. 项目简介 本项目是一个运行在 AI 眼镜上的 多模型答案对比智能体。 用户向眼镜提出一个问题后,Agent 会同时向 通义千问、DeepSeek、智谱、Kimi 等多个大模型发起请求,并将不同模型的回答整理成可对比的结果,让用户在眼镜端快速查看多路答…

2026/7/15 4:21:52阅读更多 →
Windows Home Server 2011安装指南:兼容性、驱动与家庭服务器部署

Windows Home Server 2011安装指南:兼容性、驱动与家庭服务器部署

如果你在整理旧设备时翻出一台还能开机的老电脑,或者想用最低成本搭建一个家庭文件备份和远程访问环境,可能会想到十年前那个专为家庭设计的服务器系统——Windows Home Server 2011。虽然它早已在2016年停止支持,但在某些特定场景下&#xf…

2026/7/15 5:16:57阅读更多 →
基于Qt C++的配置文件编辑器:实现数据与UI双向绑定的工程实践

基于Qt C++的配置文件编辑器:实现数据与UI双向绑定的工程实践

1. 项目概述:为什么我们需要一个自己的配置文件编辑器?在桌面软件开发中,配置文件(如INI、JSON、XML、YAML)是连接程序与用户的桥梁。它们存储着程序的设置、用户偏好、运行参数等关键信息。然而,对于非技术…

2026/7/15 5:16:57阅读更多 →
实测对比:SDIO与SPI读写SD卡,速度差距究竟有多大?

实测对比:SDIO与SPI读写SD卡,速度差距究竟有多大?

1. SDIO与SPI接口基础对比第一次接触SD卡开发时,我也曾纠结该选SPI还是SDIO接口。这两种接口虽然都能读写SD卡,但底层设计理念完全不同。SPI就像单车道乡村公路,而SDIO则是四车道高速公路。具体差异主要体现在三个方面:物理连接上…

2026/7/15 5:16:57阅读更多 →
基于NLP的体育新闻文本分析:从实体识别到情感分析的完整实战指南

基于NLP的体育新闻文本分析:从实体识别到情感分析的完整实战指南

最近在开发一个需要处理国际体育赛事数据的项目时,遇到了一个典型的技术难题:如何从非结构化的体育新闻文本中准确提取关键信息,比如比赛结果、球员表现和赛后评论。这类文本往往包含大量口语化表达和复杂句式,传统的关键词匹配方…

2026/7/15 5:16:57阅读更多 →
vivado 加密

vivado 加密

Vivado / Xilinx FPGA 的 bitstream 加密,常见核心是: AES 加密 具体用哪种,要看 FPGA 系列。 ## 1. 7 系列 / Kintex-7 / Artix-7 / Virtex-7 / Zynq-7000 常用: AES-256-CBC 也就是 256bit AES 密钥加密 bitstream。 key 可…

2026/7/15 5:16:57阅读更多 →
小熊猫C++调试模式下输出换行异常:原理分析与解决方案

小熊猫C++调试模式下输出换行异常:原理分析与解决方案

1. 项目概述:一个看似简单却令人抓狂的调试难题如果你正在使用小熊猫C进行嵌入式或控制台程序的开发,并且发现程序在调试模式下运行时,主控台(Console)的输出变得一团糟——比如本该换行的地方没有换行,或者…

2026/7/15 5:11:57阅读更多 →
VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异当你在VSCode中启动一个新的TypeScript项目时,第一个技术决策往往从安装方式开始。这个看似简单的选择——全局安装还是项目本地安装——实际上会深刻影响你的开发流程、团队协作和…

2026/7/14 4:56:14阅读更多 →
智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手 【免费下载链接】zhihuishu 智慧树刷课插件,自动播放下一集、1.5倍速度、无声 项目地址: https://gitcode.com/gh_mirrors/zh/zhihuishu 智慧树刷课插件是一款专为智慧树在线教育平台设计的Chrome浏…

2026/7/14 2:55:05阅读更多 →
Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 你是否在GOG或Epic Games Store购买了心仪的游戏…

2026/7/14 6:17:41阅读更多 →
AI框架决定企业AI能走多远

AI框架决定企业AI能走多远

企业AI建设的第一性原理 企业搞AI,最关键的决定是什么?不是选哪家大模型,不是先做哪个场景,不是招多少AI人才——而是选哪个AI开发框架。 为什么?因为框架决定了企业AI能力的"天花板"。选对了框架&#xff0…

2026/7/15 0:01:30阅读更多 →
Java企业为什么需要AI框架

Java企业为什么需要AI框架

Java企业在AI时代的尴尬处境 Java是全球企业级应用开发的主流语言——全球超过一半的企业系统跑在Java上。但在AI浪潮面前,很多Java企业感到尴尬:大模型的接口是各种语言的,AI开发社区以其他语言为主流,似乎Java在AI时代"掉队…

2026/7/15 0:01:30阅读更多 →
CC3230x嵌入式开发实战:SD主机、定时器与低功耗模式深度解析

CC3230x嵌入式开发实战:SD主机、定时器与低功耗模式深度解析

1. 项目概述:为什么需要关注CC3230x的SD主机、定时器与低功耗?在物联网和嵌入式设备开发领域,我们常常面临一个核心矛盾:设备需要具备强大的连接能力、可靠的数据存储和实时控制功能,同时又必须严格控制功耗以延长电池…

2026/7/15 0:01:30阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/14 15:07:30阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/14 4:45:36阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/14 2:42:17阅读更多 →