Skip to content

Squirrel Panel v2.0.4

Latest

Choose a tag to compare

@wolfprince12 wolfprince12 released this 06 Sep 01:15
· 3 commits to main since this release

v2.0.4 是一个纯 bug 修复版本,只做了一件事:修掉「应用适配」页删除已添加应用时面板必崩的问题。

问题现象

在「应用适配」页面,给任意应用点了最右侧的减号 → 面板立刻崩溃退出(macOS 崩溃报告:EXC_CRASH (SIGABRT),Abort trap: 6)。v2.0.3 上删除任意一个应用都会 100% 复现,不是偶发。

根因

Swift 运行时的「独占性检查」(Exclusivity Enforcement)拦下了同一次操作里的两次重叠访问:

ForEach($store.appOptions) { $entry in
  AppOptionRow(entry: $entry) {
    store.appOptions.removeAll { $0.bundleID == entry.bundleID }   // ← 必崩
  }
}
  • removeAll(where:)store.appOptions@Observable 类的存储属性)发起贯穿整个遍历的 modify(读写)访问
  • 谓词里的 entry.bundleID 来自 ForEach($store.appOptions) 派发的元素 Binding,读取时又对同一个属性发起一次 read 访问

两次访问重叠 → swift_beginAccess 检测到冲突 → fatalErrorabort()。崩溃栈第 7 帧的 key path getter for SettingsStore.availableSchemas/appOptions 与第 11–17 帧的 Binding.readValue() 完全对得上。

修复

  1. SettingsStore 新增 removeAppOption(bundleID:),删除逻辑收敛到模型层;
  2. 视图改为 store.removeAppOption(bundleID: entry.bundleID) —— bundleID 先求值成值类型再传参,读访问在调用前结束,读与写拆成两次不重叠的访问

写盘侧无需改动:compileSquirrelPatch() 本来就会按 originalAppBundleIDs 把被删条目清成 null,删除后点「应用并重新部署」照常生效。

界面零改动,其余功能与 v2.0.3 完全一致。

安装

  1. 下载下方 Squirrel-Panel-2.0.4.dmg,挂载后把 Squirrel Panel.app 拖到 Applications 覆盖旧版;
  2. 首次运行若被 Gatekeeper 拦截(本项目未做 Apple 公证),运行 DMG 内的 fix.command 放行即可;
  3. Homebrew 用户:brew upgrade --cask squirrel-panel

校验

  • swift build 通过;单元测试 64 例,2 例失败为 v2.0.3 既有问题(判脏逻辑为异步重算、测试同步断言),与本次改动无关。
  • DMG sha256:f3fe62bb07850cad1f6b2392b7a08eab9c86058c08de29f09ace79d75e4e17c2

Mr大狼 · 先求稳定,再求创新。