You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NET8 MAUI iOS上架App Store后SQLite读取崩溃求助

解决.NET 8 MAUI iOS App Store版本SQLite AOT崩溃问题

问题背景

我在.NET 8 MAUI应用中引入了以下SQLite相关NuGet包:

<PackageReference Include="Microsoft.Data.Sqlite" Version="8.0.6" />
<PackageReference Include="sqlite-net-pcl" Version="1.9.172" />
<PackageReference Include="SQLitePCLRaw.bundle_green" Version="2.1.8" />
<PackageReference Include="SQLitePCLRaw.provider.sqlite3" Version="2.1.8" />

应用需频繁读取数据库,本地调试及真机Release测试均运行正常,但上架至App Store后,读取数据库时会立即崩溃。AppCenter捕获的错误信息:

SIGABRT: Attempting to JIT compile method '(wrapper delegate-invoke) void System.Action`2<LanguageInUse.Domain.Dictionary, System.DateTime>:invoke_callvirt_void_T1_T2 (LanguageInUse.Domain.Dictionary,System.DateTime)' while running in aot-only mode.

完整错误堆栈:

SQLite.FastColumnSetter.<>c__DisplayClass2_0`2[[LanguageInUse.Domain.Dictionary, LanguageInUse, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.DateTime, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].<CreateTypedSetterDelegate>b__0(Object o, sqlite3_stmt stmt, Int32 i)
SQLite.SQLiteCommand.<ExecuteDeferredQuery>d__12`1[[LanguageInUse.Domain.Dictionary, LanguageInUse, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].MoveNext()
System.Collections.Generic.List`1[[LanguageInUse.Domain.Dictionary, LanguageInUse, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]..ctor(IEnumerable`1 )
System.Linq.Enumerable.ToList[Dictionary](IEnumerable`1 )
SQLite.SQLiteCommand.ExecuteQuery[Dictionary]()
SQLite.TableQuery`1[[LanguageInUse.Domain.Dictionary, LanguageInUse, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].ToList()
SQLite.AsyncTableQuery`1[[LanguageInUse.Domain.Dictionary, LanguageInUse, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].<ToListAsync>b__11_0(SQLiteConnectionWithLock conn)
SQLite.AsyncTableQuery`1.<>c__DisplayClass2_0`1[[LanguageInUse.Domain.Dictionary, LanguageInUse, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.Collections.Generic.List`1[[LanguageInUse.Domain.Dictionary, LanguageInUse, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].<ReadAsync>b__0()
System.Threading.Tasks.Task`1[[System.Collections.Generic.List`1[[LanguageInUse.Domain.Dictionary, LanguageInUse, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].InnerInvoke()
System.Threading.Tasks.Task.<>c.<.cctor>b__281_0(Object obj)
System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread , ExecutionContext , ContextCallback , Object )
System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread , ExecutionContext , ContextCallback , Object )
System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& , Thread )
LanguageInUse.Persistence.LIUDatabase.GetDictionariesForSearchAsync(String username, String search)
LanguageInUse.ViewModels.DictionaryListViewModel.<Init>b__13_0(Object s, PopupOpenedEventArgs e)
System.Threading.Tasks.Task.<>c.<ThrowAsync>b__128_0(Object state)
Foundation.NSAsyncSynchronizationContextDispatcher.Apply()
ObjCRuntime.Runtime.ThrowException(IntPtr )
UIKit.UIApplication.UIApplicationMain(Int32 , String[] , IntPtr , IntPtr )
UIKit.UIApplication.Main(String[] , Type , Type )
LanguageInUse.Program.Main(String[] args)

此前尝试过降级SQLite版本、配置<UseInterpreter>true</UseInterpreter>和<MtouchInterpreter>-all</MtouchInterpreter>,但不想再提交存在问题的版本,需要有效解决方案。

解决方案

1. 禁用sqlite-net-pcl的FastColumnSetter

问题根源是sqlite-net-pcl的FastColumnSetter在AOT环境下会动态生成委托触发JIT编译,可在初始化SQLite连接时关闭该特性:

var connection = new SQLiteAsyncConnection(dbPath, SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.Create, false);
// 禁用FastColumnSetter,避免动态委托生成
connection.Connection.UserParameters.Add("FastColumnSetter", false);

2. 升级sqlite-net-pcl到最新稳定版

sqlite-net-pcl后续版本(如2.1.0及以上)针对.NET MAUI的AOT兼容性做了优化,替换NuGet引用为最新稳定版:

<PackageReference Include="sqlite-net-pcl" Version="2.1.0" /> <!-- 替换为实际最新稳定版 -->

3. 添加AOT编译提示

若无法升级包或禁用FastColumnSetter,可在项目中添加AOT提示文件(如AOTRuntimeHints.cs),告知编译器预编译相关类型和委托:

using System.Runtime.CompilerServices;
using LanguageInUse.Domain;

// 预编译实体类和相关委托类型
[assembly: RuntimeHelpers.RunClassConstructor(typeof(Dictionary).TypeHandle)]
[assembly: RuntimeHelpers.RunClassConstructor(typeof(System.Action<Dictionary, System.DateTime>).TypeHandle)]

同时在iOS项目的.csproj中添加配置,防止编译器裁剪相关类型:

<ItemGroup>
  <TrimmerRootAssembly Include="LanguageInUse" />
</ItemGroup>

4. 替换为Microsoft.Data.Sqlite+Dapper组合

若sqlite-net-pcl的AOT问题无法彻底解决,可改用Microsoft.Data.Sqlite配合轻量ORM(如Dapper),完全基于静态编译避免JIT问题:

using Microsoft.Data.Sqlite;
using Dapper;

public async Task<List<Dictionary>> GetDictionariesForSearchAsync(string username, string search)
{
    using var conn = new SqliteConnection($"Data Source={dbPath}");
    await conn.OpenAsync();
    var query = "SELECT * FROM Dictionary WHERE Username = @Username AND Name LIKE @Search";
    return (await conn.QueryAsync<Dictionary>(query, new { Username = username, Search = $"%{search}%" })).ToList();
}

内容的提问来源于stack exchange,提问作者Enrico

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 19:07:33