fix(ios): guard Darwin style CoreOnly layer peer access
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled
This commit is contained in:
41
docs/50_Step记录/STEP-107_iOS_StyleCoreOnlyPeer集合修复_v1.md
Normal file
41
docs/50_Step记录/STEP-107_iOS_StyleCoreOnlyPeer集合修复_v1.md
Normal 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`。
|
||||
42
docs/报告/STEP-107_iOS_StyleCoreOnlyPeer集合修复_RDC实施报告_v1.md
Normal file
42
docs/报告/STEP-107_iOS_StyleCoreOnlyPeer集合修复_RDC实施报告_v1.md
Normal 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 执行。
|
||||
@@ -283,12 +283,20 @@ const MLNExceptionName MLNRedundantSourceIdentifierException =
|
||||
// MARK: Style layers
|
||||
|
||||
- (NSArray<__kindof MLNStyleLayer *> *)layers {
|
||||
auto layers = self.rawStyle->getLayers();
|
||||
// Core-only layers (including Particle and WeatherColor) are intentionally
|
||||
// not exposed as Objective-C peers. Keep them in the native Style for
|
||||
// rendering, but never insert a missing peer into an NSArray.
|
||||
auto rawLayers = self.rawStyle->getLayers();
|
||||
NSMutableArray<__kindof MLNStyleLayer *> *styleLayers =
|
||||
[NSMutableArray arrayWithCapacity:layers.size()];
|
||||
for (auto layer : layers) {
|
||||
MLNStyleLayer *styleLayer = [self layerFromMBGLLayer:layer];
|
||||
[styleLayers addObject:styleLayer];
|
||||
[NSMutableArray arrayWithCapacity:rawLayers.size()];
|
||||
for (auto rawLayer : rawLayers) {
|
||||
MLNStyleLayer *styleLayer = [self layerFromMBGLLayer:rawLayer];
|
||||
if (styleLayer) {
|
||||
[styleLayers addObject:styleLayer];
|
||||
} else {
|
||||
MLNLogDebug(@"Skipping native-only style layer id=%s type=%s (no ObjC peer)",
|
||||
rawLayer->getID().c_str(), rawLayer->getTypeInfo()->type);
|
||||
}
|
||||
}
|
||||
return styleLayers;
|
||||
}
|
||||
@@ -304,30 +312,30 @@ const MLNExceptionName MLNRedundantSourceIdentifierException =
|
||||
}
|
||||
|
||||
- (NSUInteger)countOfLayers {
|
||||
return self.rawStyle->getLayers().size();
|
||||
// KVC indices count the same ObjC-visible layers as the public getter.
|
||||
return self.layers.count;
|
||||
}
|
||||
|
||||
- (MLNStyleLayer *)objectInLayersAtIndex:(NSUInteger)index {
|
||||
auto layers = self.rawStyle->getLayers();
|
||||
if (index >= layers.size()) {
|
||||
NSArray<MLNStyleLayer *> *visibleLayers = self.layers;
|
||||
if (index >= visibleLayers.count) {
|
||||
[NSException raise:NSRangeException
|
||||
format:@"No style layer at index %lu.", (unsigned long)index];
|
||||
return nil;
|
||||
}
|
||||
auto layer = layers.at(index);
|
||||
return [self layerFromMBGLLayer:layer];
|
||||
return visibleLayers[index];
|
||||
}
|
||||
|
||||
- (void)getLayers:(MLNStyleLayer **)buffer range:(NSRange)inRange {
|
||||
auto layers = self.rawStyle->getLayers();
|
||||
if (NSMaxRange(inRange) > layers.size()) {
|
||||
NSArray<MLNStyleLayer *> *visibleLayers = self.layers;
|
||||
if (inRange.location > visibleLayers.count ||
|
||||
inRange.length > visibleLayers.count - inRange.location) {
|
||||
[NSException raise:NSRangeException
|
||||
format:@"Style layer range %@ is out of bounds.", NSStringFromRange(inRange)];
|
||||
return;
|
||||
}
|
||||
NSUInteger i = 0;
|
||||
for (auto layer = *(layers.rbegin() + inRange.location); i < inRange.length; ++layer, ++i) {
|
||||
MLNStyleLayer *styleLayer = [self layerFromMBGLLayer:layer];
|
||||
buffer[i] = styleLayer;
|
||||
for (NSUInteger i = 0; i < inRange.length; ++i) {
|
||||
buffer[i] = visibleLayers[inRange.location + i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,37 +347,26 @@ const MLNExceptionName MLNRedundantSourceIdentifierException =
|
||||
@"of MLNStyleLayer.",
|
||||
styleLayer];
|
||||
}
|
||||
auto layers = self.rawStyle->getLayers();
|
||||
if (index > layers.size()) {
|
||||
NSArray<MLNStyleLayer *> *visibleLayers = self.layers;
|
||||
if (index > visibleLayers.count) {
|
||||
[NSException
|
||||
raise:NSRangeException
|
||||
format:@"Cannot insert style layer at out-of-bounds index %lu.", (unsigned long)index];
|
||||
} else if (index == 0) {
|
||||
try {
|
||||
MLNStyleLayer *sibling = layers.size() ? [self layerFromMBGLLayer:layers.at(0)] : nil;
|
||||
[styleLayer addToStyle:self belowLayer:sibling];
|
||||
} catch (const std::runtime_error &err) {
|
||||
[NSException raise:MLNRedundantLayerIdentifierException format:@"%s", err.what()];
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
MLNStyleLayer *sibling = [self layerFromMBGLLayer:layers.at(index)];
|
||||
[styleLayer addToStyle:self belowLayer:sibling];
|
||||
} catch (std::runtime_error &err) {
|
||||
[NSException raise:MLNRedundantLayerIdentifierException format:@"%s", err.what()];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Insert before the next visible layer, or above the entire native stack.
|
||||
// Indices exposed to KVC must not count hidden core-only layers.
|
||||
MLNStyleLayer *sibling = index < visibleLayers.count ? visibleLayers[index] : nil;
|
||||
try {
|
||||
[styleLayer addToStyle:self belowLayer:sibling];
|
||||
} catch (const std::runtime_error &err) {
|
||||
[NSException raise:MLNRedundantLayerIdentifierException format:@"%s", err.what()];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)removeObjectFromLayersAtIndex:(NSUInteger)index {
|
||||
auto layers = self.rawStyle->getLayers();
|
||||
if (index >= layers.size()) {
|
||||
[NSException
|
||||
raise:NSRangeException
|
||||
format:@"Cannot remove style layer at out-of-bounds index %lu.", (unsigned long)index];
|
||||
}
|
||||
auto layer = layers.at(index);
|
||||
MLNStyleLayer *styleLayer = [self layerFromMBGLLayer:layer];
|
||||
MLNStyleLayer *styleLayer = [self objectInLayersAtIndex:index];
|
||||
[styleLayer removeFromStyle:self];
|
||||
}
|
||||
|
||||
@@ -466,36 +463,22 @@ const MLNExceptionName MLNRedundantSourceIdentifierException =
|
||||
sibling];
|
||||
}
|
||||
|
||||
auto layers = self.rawStyle->getLayers();
|
||||
std::string siblingIdentifier = sibling.identifier.UTF8String;
|
||||
NSUInteger index = 0;
|
||||
for (auto siblingLayer : layers) {
|
||||
if (siblingLayer->getID() == siblingIdentifier) {
|
||||
break;
|
||||
}
|
||||
index++;
|
||||
// A hidden core-only layer may immediately follow sibling in the native
|
||||
// stack. Find the next *visible* sibling to avoid passing a nil ObjC peer
|
||||
// to addToStyle:belowLayer:.
|
||||
NSArray<MLNStyleLayer *> *visibleLayers = self.layers;
|
||||
NSUInteger siblingIndex = [visibleLayers
|
||||
indexOfObjectPassingTest:^BOOL(MLNStyleLayer *candidate, NSUInteger idx, BOOL *stop) {
|
||||
return [candidate.identifier isEqualToString:sibling.identifier];
|
||||
}];
|
||||
if (siblingIndex == NSNotFound) {
|
||||
[NSException raise:NSInvalidArgumentException
|
||||
format:@"The sibling layer %@ is not present in this style.", sibling];
|
||||
return;
|
||||
}
|
||||
|
||||
[self willChangeValueForKey:@"layers"];
|
||||
if (index + 1 > layers.size()) {
|
||||
[NSException raise:NSInvalidArgumentException
|
||||
format:@"A style layer cannot be placed above %@ in the style. "
|
||||
@"Make sure sibling was obtained using -[MLNStyle layerWithIdentifier:].",
|
||||
sibling];
|
||||
} else if (index + 1 == layers.size()) {
|
||||
try {
|
||||
[layer addToStyle:self belowLayer:nil];
|
||||
} catch (std::runtime_error &err) {
|
||||
[NSException raise:MLNRedundantLayerIdentifierException format:@"%s", err.what()];
|
||||
}
|
||||
} else {
|
||||
MLNStyleLayer *nextSibling = [self layerFromMBGLLayer:layers.at(index + 1)];
|
||||
try {
|
||||
[layer addToStyle:self belowLayer:nextSibling];
|
||||
} catch (std::runtime_error &err) {
|
||||
[NSException raise:MLNRedundantLayerIdentifierException format:@"%s", err.what()];
|
||||
}
|
||||
}
|
||||
[self insertObject:layer inLayersAtIndex:siblingIndex + 1];
|
||||
[self didChangeValueForKey:@"layers"];
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
#import <Mapbox.h>
|
||||
|
||||
#import "MLNStyle_Private.h"
|
||||
#import "MLNVectorTileSource_Private.h"
|
||||
|
||||
#include <mln/style/layers/particle_validation_layer.hpp>
|
||||
#include <mln/style/style.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#import "NSBundle+MLNAdditions.h"
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
@@ -238,6 +245,70 @@
|
||||
XCTAssertEqual(self.style.layers.count, initialLayers.count);
|
||||
}
|
||||
|
||||
// Native-only layers must remain renderable while ObjC/KVC accessors expose
|
||||
// only layers for which Darwin can construct a valid MLNStyleLayer peer.
|
||||
- (void)testCoreOnlyLayersPreserveObjCCollectionAndOrdering {
|
||||
NSUInteger initialCount = self.style.layers.count;
|
||||
NSUInteger initialNativeCount = self.style.rawStyle->getLayers().size();
|
||||
|
||||
MLNShapeSource *source = [[MLNShapeSource alloc] initWithIdentifier:@"core-only-test-source"
|
||||
shape:nil
|
||||
options:nil];
|
||||
[self.style addSource:source];
|
||||
|
||||
MLNCircleStyleLayer *lower = [[MLNCircleStyleLayer alloc]
|
||||
initWithIdentifier:@"core-only-visible-lower" source:source];
|
||||
MLNCircleStyleLayer *upper = [[MLNCircleStyleLayer alloc]
|
||||
initWithIdentifier:@"core-only-visible-upper" source:source];
|
||||
[self.style addLayer:lower];
|
||||
[self.style addLayer:upper];
|
||||
|
||||
// Mix hidden core layers between and above the public ObjC layers.
|
||||
self.style.rawStyle->addLayer(
|
||||
std::make_unique<mln::style::ParticleValidationLayer>("core-only-middle"),
|
||||
std::string("core-only-visible-upper"));
|
||||
self.style.rawStyle->addLayer(
|
||||
std::make_unique<mln::style::ParticleValidationLayer>("core-only-top"));
|
||||
|
||||
NSArray<MLNStyleLayer *> *visible = self.style.layers;
|
||||
XCTAssertEqual(visible.count, initialCount + 2);
|
||||
XCTAssertEqual([self.style countOfLayers], initialCount + 2);
|
||||
XCTAssertEqual(self.style.rawStyle->getLayers().size(), initialNativeCount + 4);
|
||||
XCTAssertEqualObjects(visible[initialCount].identifier, lower.identifier);
|
||||
XCTAssertEqualObjects(visible[initialCount + 1].identifier, upper.identifier);
|
||||
XCTAssertNil([self.style layerWithIdentifier:@"core-only-middle"]);
|
||||
XCTAssertNotNil(self.style.rawStyle->getLayer("core-only-middle"));
|
||||
XCTAssertNotNil(self.style.rawStyle->getLayer("core-only-top"));
|
||||
|
||||
id kvcStyle = self.style;
|
||||
XCTAssertEqualObjects([kvcStyle objectInLayersAtIndex:initialCount], lower);
|
||||
MLNStyleLayer *__unsafe_unretained rangeLayers[2] = {nil, nil};
|
||||
[kvcStyle getLayers:rangeLayers range:NSMakeRange(initialCount, 2)];
|
||||
XCTAssertEqualObjects(rangeLayers[0], lower);
|
||||
XCTAssertEqualObjects(rangeLayers[1], upper);
|
||||
XCTAssertThrowsSpecificNamed([kvcStyle objectInLayersAtIndex:visible.count], NSException,
|
||||
NSRangeException);
|
||||
|
||||
// The native layer immediately above lower lacks an ObjC peer. Inserting
|
||||
// above lower must still work and retain the relative visible order.
|
||||
MLNCircleStyleLayer *above = [[MLNCircleStyleLayer alloc]
|
||||
initWithIdentifier:@"core-only-visible-above" source:source];
|
||||
[self.style insertLayer:above aboveLayer:lower];
|
||||
XCTAssertEqualObjects(self.style.layers[initialCount + 1], above);
|
||||
XCTAssertEqualObjects(self.style.layers[initialCount + 2], upper);
|
||||
|
||||
// KVC's index applies to public peers, not the internal native stack.
|
||||
MLNCircleStyleLayer *inserted = [[MLNCircleStyleLayer alloc]
|
||||
initWithIdentifier:@"core-only-visible-inserted" source:source];
|
||||
[self.style insertLayer:inserted atIndex:initialCount + 1];
|
||||
XCTAssertEqualObjects(self.style.layers[initialCount + 1], inserted);
|
||||
[kvcStyle removeObjectFromLayersAtIndex:initialCount + 1];
|
||||
XCTAssertNil([self.style layerWithIdentifier:inserted.identifier]);
|
||||
XCTAssertEqualObjects(self.style.layers[initialCount + 1], above);
|
||||
XCTAssertNotNil(self.style.rawStyle->getLayer("core-only-middle"));
|
||||
XCTAssertNotNil(self.style.rawStyle->getLayer("core-only-top"));
|
||||
}
|
||||
|
||||
- (void)testAddingLayersTwice {
|
||||
MLNShapeSource *source = [[MLNShapeSource alloc] initWithIdentifier:@"shapeSource"
|
||||
shape:nil
|
||||
|
||||
@@ -1081,3 +1081,11 @@ Android V3-08 单次综合验收已完成并关闭。Native `13.4.1-particle.2`
|
||||
- Metal `bazel build -c opt --//:renderer=metal //:mbgl-core` 构建 PASS(642/642,875.118s,产物 `bazel-bin/libmbgl-core.a`)。
|
||||
- Mac CMake/GTest 配置遇缺失 `libuv`,未安装依赖,正式 GTest NOT RUN。
|
||||
- 修复 STEP-102 Android Validation 入口切换时残留 STEP-093/097 状态与轮询的问题。Android APK 编译、T1/T2 真机及 STEP-100/101 回归仍待手工构建与运行;STEP-102 维持“进行中”,尚非 CLOSED/PASS。
|
||||
|
||||
|
||||
### 2026-10-09 STEP-107 iOS CoreOnly Style Peer 崩溃修复(Native BUILD PASS,iPad 待验收)
|
||||
|
||||
- 基于远端最新 `particle/main` 的 V22 后 HEAD `24105b1be7`,在唯一 Mac 主目录直接修复 Darwin `MLNStyle.layers` 对 CoreOnly 无 Peer Layer 的 nil 插入问题;补齐 KVC 数量/索引/区间、插入/删除与 aboveLayer ObjC 可见顺序语义,Native 粒子天气渲染层保持不变。
|
||||
- 新增 `MLNStyleTests.mm` 混合 CoreOnly/普通 Layer 的集合及顺序回归用例;`git diff --check` PASS。Mac Bazel iOS Native `//platform/ios:MapLibre.dynamic` PASS,982.084 秒,ZIP 校验 PASS,SHA-256 `f16b7f2be761a101bb4b906b900175b95412abfeef09d715e2c9321b300a7b8a`。
|
||||
- XCTest 尚未执行;iPad 唐津海图物体直接点击、多 Source、天气开关及粒子渲染尚未真实验收;不能宣称 Bug 已在设备上消失。未修改 V22 Tag、正式发行资料、NavSea、Android 或 Shared Core。
|
||||
- Step:`docs/50_Step记录/STEP-107_iOS_StyleCoreOnlyPeer集合修复_v1.md`;报告:`docs/报告/STEP-107_iOS_StyleCoreOnlyPeer集合修复_RDC实施报告_v1.md`。
|
||||
|
||||
Reference in New Issue
Block a user