fix(ios): guard Darwin style CoreOnly layer peer access
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled

This commit is contained in:
tei
2026-10-09 21:46:59 +09:00
parent 24105b1be7
commit 016bf5ad93
5 changed files with 212 additions and 67 deletions

View File

@@ -0,0 +1,41 @@
# STEP-107 iOS Style CoreOnly Peer 集合一致性修复 v1
- 日期:2026-10-09(JST)
- 状态:**进行中 / iOS Native 构建 PASS / XCTest 与 iPad 实机回归未执行**
- 机器:Mac.lan;源码:`/Users/tei/dev/MapLibreParticleLab`;分支:`particle/main`
- 开工 HEAD:`24105b1be7a2c8bd3a547117a30887fbaa0a308b`
- 对应调查:`docs/20_调查/iOS地图点击重叠Source触发MLNStyle空Peer崩溃调查_v1.md`
- 涉及的已正式发行基线:`maplibre-particle/rn/13.6.1-particle.22`(不修改原 Tag / Source Lock)。
## 目标与边界
消除 Darwin `MLNStyle.layers` 因 CoreOnly Layer 没有 ObjC Peer 而插入 nil 引发的 NSInvalidArgumentException;统一 `layers`、KVC 数量/索引/区间访问与增删位置语义,保持 C++ 原始 Style 的 CoreOnly 渲染能力以及可点击 ObjC 层的可见 Z-order。
只允许修复 Darwin `MLNStyle.mm`、对应 iOS XCTest、Step 与报告;不得修改 NavSea、RN 11.5.0 依赖、Android、Shared Core、粒子 Shader/Renderer、V22 已发布内容或已有工作树。不得新建 worktree,禁用 Jest;不把编译通过等同 iPad 修复验收。
## 本轮实施
- [x] 检查实际 Native `MLNStyle.layers` 中未判空的 `addObject:`,及 `LayerManagerDarwin::createPeer` 对 CoreOnly 类型返回空的现状。
- [x] getter 仅暴露有效 ObjC Peer,跳过无 Peer CoreOnly Layer;DEBUG 日志包含不可桥接 Layer ID/类型,以便后续现场确认触发者。
- [x] `countOfLayers`、`objectInLayersAtIndex:`、`getLayers:range:` 统一使用 ObjC 可见集;修正原区间 getter 的反向遍历顺序。
- [x] ObjC 可见索引用于 `insertObject:inLayersAtIndex:`、`removeObjectFromLayersAtIndex:`;`insertLayer:aboveLayer:` 使用下一个可见 sibling,防止隐藏 CoreOnly 层造成 nil。
- [x] 补充 `MLNStyleTests.mm` 定向 XCTest,构造 Native-only Layer 与普通 Layer 混合、索引/顺序/增删场景。
- [x] `git diff --check` PASS。
- [x] RDC 在 Mac 执行 `bazel build //platform/ios:MapLibre.dynamic --color=no --curses=no --show_progress_rate_limit=15`,exit 0,Build completed successfully(982.084 秒)。
- [x] XCFramework ZIP 存在、`unzip -tqq` PASS,SHA-256:`f16b7f2be761a101bb4b906b900175b95412abfeef09d715e2c9321b300a7b8a`。
- [ ] 运行新增 `MLNStyleTests` XCTest,包括 KVC 索引与 CoreOnly 层回归。
- [ ] 使用实际 iPad 和此修复构建的 Native 验证「唐津ヨット ハーバ」直接点击、多 Source 重叠、十字光标、天气开关及粒子渲染。
- [ ] 从真实日志确认当次缺失 Peer 的具体 Layer ID/type;若原因超出 CoreOnly 假设,应补充分析。
- [ ] 如进入正式发行,按 GSRL 创建**新版本**、独立构建与 Source Lock,并做公网校验;不得改写 V22。
## 事实与遗留
新增 XCTest 源码已编写,但本轮 Bazel XCFramework 构建目标不包含 Darwin XCTest,故不能声称测试 PASS;实际 iPad 未测试。编译日志路径:`/tmp/maplibre_v22_ios_style_fix_bazel_20261009.log`。编译警告仅见无效搜索路径 `/opt/homebrew/lib`,不影响构建。构建产物为未发行验证 ZIP,不是 V22 原版或正式新版本。
原本就存在的 `vendor/expected-lite` 子模块本地状态与两份未跟踪文档必须保持原状。
## 下一步
由 Particle-iOS 在 Mac 真正执行 Darwin XCTest,必要时改正测试编译接口,再由用户将包含本次修复的 iOS Native 安装到 iPad 重放现场;上述验收未完成前仅按 PARTIAL / 待实机验收处理。不得转 NavSea JS workaround 或修改跨平台业务契约。
报告:`docs/报告/STEP-107_iOS_StyleCoreOnlyPeer集合修复_RDC实施报告_v1.md`。

View File

@@ -0,0 +1,42 @@
# STEP-107 iOS Style CoreOnly Peer 集合修复 — RDC 实施报告 v1
## 1. 执行结论
**PARTIAL(代码已实施,iOS Native 构建 PASS,XCTest 与 iPad 事故场景 NOT RUN)**。
2026-10-09,直接在 Mac `/Users/tei/dev/MapLibreParticleLab` 的 `particle/main` 执行;没有创建 worktree、没有运行 Codex;未触碰 NavSea / Android / Shared Core / 任何正式发行 Tag。实际仍未获知崩溃现场的具体 nil Layer id/type。
## 2. Git 基线与修改范围
- 开工 HEAD:`24105b1be7a2c8bd3a547117a30887fbaa0a308b`,对应远端 `particle/main`。
- 修改:`platform/darwin/src/MLNStyle.mm` 与 `platform/darwin/test/MLNStyleTests.mm`。
- 新增:本报告、`docs/50_Step记录/STEP-107_iOS_StyleCoreOnlyPeer集合修复_v1.md`,追加 `粒子开发记录.md`。
- 与本任务无关的 `vendor/expected-lite` 子模块状态及原有两份未跟踪文档均保留。
- 未运行 Codex,因此 Codex 模型/推理档位及 Codex 完成事件不适用。
- 提交/PUSH 与远端校验以本报告后续 Git 核验补录为准。
## 3. 根因与实现
在 `MLNStyle.mm`,原 `layers` getter 对 `layerFromMBGLLayer:` 的 nil 返回直接调用 `addObject:`,遇到 CoreOnly Layer 则触发 Objective-C `NSInvalidArgumentException`。ParticleValidation、RasterParticle、WeatherColor 在 Darwin `MLNStyleLayerManager.mm` 仅注册 Core Factory,不具备 ObjC Peer。
修复后的 ObjC `layers` 只暴露有 Peer 的普通层,保留 C++ Style 内全部 CoreOnly Layer;缺失 Peer 时记录 DEBUG ID/type。KVC `countOfLayers`、单索引、range getter、插入/删除索引,以及 `aboveLayer:` 均按同一 ObjC 可见顺序处理。保持原始 C++ Style 与实际渲染的 Layer 存在及次序,不借由移除 Particle/Weather 来绕过问题。
新增 XCTest 用例通过 source-less `ParticleValidationLayer` 模拟夹在两个普通 Circle Layer 中间、以及位于顶部的 CoreOnly 层,验证 getter、KVC、区间读取、层标识、above/atIndex 插入和删除后 Native 层仍在。此 XCTest 尚未执行。
## 4. 验证记录
- `git diff --check`:PASS。
- Mac Xcode 26.3 / Bazel 8.6.0:
`bazel build //platform/ios:MapLibre.dynamic --color=no --curses=no --show_progress_rate_limit=15`:**PASS**,exit 0,耗时 982.084 秒,691 actions。
- 构建日志:`/tmp/maplibre_v22_ios_style_fix_bazel_20261009.log`。
- 新 XCFramework ZIP:`bazel-bin/platform/ios/MapLibre.dynamic.xcframework.zip`,SHA-256 `f16b7f2be761a101bb4b906b900175b95412abfeef09d715e2c9321b300a7b8a`;`unzip -tqq` PASS。
- 编译警告:链接器提示 `/opt/homebrew/lib` 不存在,但整个 Build PASS。
- `MLNStyleTests.mm` XCTest:**NOT RUN**,Bazel XCFramework 目标不包含测试文件。
- iOS Test Host / iPad / 唐津原始点击 / 双 Source Z-order / 天气粒子组合:**NOT RUN**。
- Android、Gradle、ADB、Jest、NavSea、正式 Release/Tag/Source Lock:**NOT RUN**。
## 5. 阻塞与验收边界
Native 编译 PASS 不代表原始崩溃完全修复。需运行 XCTest 并用包含本次改动的新 Native 二进制真机重放:普通对象、唐津港湾直接点击、两个以上可点击 Source、十字光标、天气粒子 Layer 开关和 Style 变更。需核实 DEBUG 输出实际无 Peer Layer 的 id/type,不应将 CoreOnly 推断当作唯一已证实源。
原 V22 正式 Tag 和分发 ZIP 未修改,当前构建仅作为本地未发行验证制品。任何正式版本迭代需新 Tag / Source Lock / SHA-256 / 远端校验,按 GSRL 执行。