三国卡牌客户端基础资源仓库
yyl
2026-07-01 b3fee9d7d77b8e3e79123fbd440c7bcc7ada96f8
加入Sort实例 防止崩溃(final test)
1个文件已修改
57 ■■■■ 已修改文件
Assets/Launch/AOTRefSort.cs 57 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Launch/AOTRefSort.cs
@@ -1,22 +1,61 @@
using System;
using System.Collections.Generic;
using UnityEngine.Scripting;
/// <summary>
/// 为 List&lt;T&gt;.Sort(lambda) / Sort() 提供 AOT 泛型实例化兜底。
/// 按 HybridCLR 泛型共享规则,class 引用类型只需实例化 object 版本。
/// 若 HeroDebutGiftItem 之类是值类型,需额外添加精确版本。
/// 为 List&lt;T&gt;.Sort / Array.Sort 提供 AOT 泛型实例化兜底。
///
/// 【为什么必须手写】
/// List&lt;T&gt;.Sort 运行时会走到 ArraySortHelper&lt;T&gt;、Comparer&lt;T&gt;.Default → GenericComparer&lt;T&gt;
/// 这些 BCL 内部类,它们的泛型实例化是通过 RuntimeTypeHandle 反射实例化出来的,
/// 静态扫描器(AOTGenericReferences)永远扫不出来 —— 所以重新生成多少次都没用,必须手写。
///
/// 【泛型共享规则】
/// - 引用类型(class):共享 object 版本,写一个 object 即可覆盖所有引用类型;
/// - 值类型(struct/enum/int...):不共享,每个用到的值类型都必须在这里精确实例化,否则 iOS 上崩。
///
/// 【新增排序类型时】:在 Ensure() 里加一行 EnsureSortable&lt;你的值类型&gt;(...) 即可。
/// </summary>
[Preserve]
public static class AOTRefSort
{
    // 阻止 IL2CPP 把排序调用当作无副作用而优化掉
    private static volatile int s_sink;
    // 由 Launch.StartGame 调用,防止 IL2CPP 裁剪
    [Preserve]
    public static void Ensure()
    {
        // Sort(lambda) 完整链路: List.Sort → ArraySortHelper.Sort → Comparison.Invoke
        var list = new List<object> { new object(), new object() };
        list.Sort((a, b) => 0);
        // 引用类型:object 版本覆盖所有 class(含自定义类、string 等)
        EnsureSortable<object>(new object(), new object());
        // Sort() 无参: 需要 IComparable,用 string(class → 共享 object)
        var list2 = new List<string> { "b", "a" };
        list2.Sort();
        // 值类型:项目里实际 Sort 的主要是 List<int>,值类型不共享须精确实例化
        EnsureSortable<int>(1, 0);
    }
    /// <summary>
    /// 精确实例化类型 T 的整条排序调用链:
    /// Sort() / Sort(Comparison) / Sort(IComparer) / Array.Sort / Comparer&lt;T&gt;.Default。
    /// 传两个不同的样本值,保证列表长度 &gt; 1,真正走进内部 IntrospectiveSort。
    /// </summary>
    [Preserve]
    private static void EnsureSortable<T>(T a, T b)
    {
        // Sort(Comparison<T>) → ArraySortHelper<T>.Sort(Span<T>, Comparison<T>)
        var list = new List<T> { a, b };
        list.Sort((x, y) => 0);
        // Sort(IComparer<T>) + Sort() → Comparer<T>.Default → GenericComparer<T>/ObjectComparer<T>
        var cmp = Comparer<T>.Default;
        list.Sort(cmp);
        list.Sort();
        // Array.Sort<T> 的三条常用重载
        var arr = new T[] { a, b };
        Array.Sort(arr);
        Array.Sort(arr, (x, y) => 0);
        Array.Sort(arr, cmp);
        s_sink += list.Count + arr.Length;
    }
}