Xamarin.Forms iOS使用Syncfusion SfButton导航返回崩溃问题
问题现象
在Xamarin.Forms应用中,从支持跳转至其他页面的页面执行返回操作后,应用停止响应所有交互,Visual Studio输出栏打印原生崩溃报告,提示执行原生代码时触发segv段错误,通常表明mono运行时或应用引用的原生库发生致命错误。该异常仅在iOS端出现,Android端相同逻辑运行完全正常,怀疑iOS端导航实现存在遗漏的特殊配置步骤。
测试环境
iOS端调试使用的模拟器为运行iOS 15.4系统的iPhone 13。
相关实现代码
MainVM导航逻辑
public async void ToFourth() { await Device.InvokeOnMainThreadAsync(() => Application.Current.MainPage.Navigation.PushAsync(new FourthPage())); //await Application.Current.MainPage.Navigation.PushAsync(new FourthPage()); } public Command TestCommand4 { get; set; } public MainVM() { TestCommand4 = new Command(ToFourth); }
FourthVM导航逻辑
public FourthVM() { ToFifthCommand = new Command(ToFifth); } public Command ToFifthCommand{ get; set; } public async void ToFifth() { await Device.InvokeOnMainThreadAsync(() => Application.Current.MainPage.Navigation.PushAsync(new FifthPage())); //await Application.Current.MainPage.Navigation.PushAsync(new FifthPage()); }
MainPage.xaml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="HelloWorldPublishTestForiOS.MainPage" xmlns:buttons="clr-namespace:Syncfusion.XForms.Buttons;assembly=Syncfusion.Buttons.XForms"> <StackLayout> <buttons:SfButton Text="To fourth page" CornerRadius="5" Command="{Binding TestCommand4}"/> </StackLayout>
FourthPage.xaml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="HelloWorldPublishTestForiOS.FourthPage" xmlns:buttons="clr-namespace:Syncfusion.XForms.Buttons;assembly=Syncfusion.Buttons.XForms"> <ContentPage.Content> <StackLayout> <buttons:SfButton Text="To Fifth Page!" VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand" Command="{Binding ToFifthCommand}"/> </StackLayout> </ContentPage.Content>
FifthPage.xaml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="HelloWorldPublishTestForiOS.FifthPage"> <ContentPage.Content> <StackLayout> <Label Text="Fifth Page!" VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand" /> </StackLayout> </ContentPage.Content> </ContentPage>
FifthVM
class FifthVM { }
复现路径
iOS端运行应用时,用户可正常从MainPage跳转至FourthPage,也可在FourthPage和FifthPage之间正常往返,但一旦返回MainPage后,跳转FourthPage的按钮就会失效,输出栏返回前述原生崩溃报错。
错误栈关键信息
托管栈追踪显示崩溃发生在Syncfusion.XForms.iOS.Buttons.SfButtonRenderer的Dispose流程中,调用UIColor.CGColor属性时触发原生段错误。
排查进展
- 当前iOS端AppDelegate中Syncfusion控件初始化顺序为:先调用
Xamarin.Forms.Forms.Init()、LoadApplication(new App()),再调用SfBorderRenderer.Init()、SfButtonRenderer.Init()、Core.Init(); - 项目仅安装
Syncfusion.Xamarin.Buttons、Syncfusion.Xamarin.Buttons.iOS、Syncfusion.Xamarin.Core三个Syncfusion相关NuGet包; - 将XAML中的
SfButton替换为Xamarin.Forms原生Button控件后,导航功能完全正常,崩溃仅在使用SfButton执行导航操作时出现。
根因与修复方案
根因
崩溃核心原因是Syncfusion iOS端渲染器初始化顺序错误。Syncfusion控件要求所有渲染器的Init方法必须在LoadApplication(new App())调用前执行,否则会导致渲染器实例生命周期管理异常,页面弹出销毁时,渲染器的Dispose流程会访问已被释放的原生UI资源(本次崩溃中就是已释放的UIColor对应的CGColor野指针),触发段错误。
修复步骤
- 调整iOS项目
AppDelegate.cs中FinishedLaunching方法内的初始化顺序,将所有Syncfusion渲染器的Init调用移动到LoadApplication之前,正确顺序参考如下代码:
public override bool FinishedLaunching(UIApplication app, NSDictionary options) { global::Xamarin.Forms.Forms.Init(); // 所有Syncfusion渲染器初始化必须放在LoadApplication之前 Syncfusion.XForms.iOS.Core.SfCoreRenderer.Init(); Syncfusion.XForms.iOS.Border.SfBorderRenderer.Init(); Syncfusion.XForms.iOS.Buttons.SfButtonRenderer.Init(); // 初始化完成后再加载应用 LoadApplication(new App()); return base.FinishedLaunching(app, options); }
- 清理项目所有bin、obj目录,重新生成部署即可解决崩溃问题。
内容的提问来源于stack exchange,提问作者HamdyAli
相关产品推荐
相关产品推荐

