使用SKGLView时从其他页面返回MainPage触发崩溃如何解决?
SIGABRT:无法访问已释放的对象。对象名:“SKGLView”。
问题根因
这个崩溃的本质是已销毁的原生控件被异步回调访问:当你从MainPage跳转到其他页面时,iOS平台会自动回收SKGLView对应的原生GLKView资源,但是SkiaSharp的渲染队列中还有未执行的异步绘制任务,任务执行时尝试调用已经被销毁的GLKView的Display方法,就触发了对象已释放异常。
修复方案
方案1:生命周期联动控制(推荐,改动最小)
在MainPage的生命周期方法中手动控制SKGLView的渲染状态:protected override void OnDisappearing() { base.OnDisappearing(); // 离开页面时暂停渲染,清空待执行任务 if (!skglView.IsDisposed) { skglView.Pause(); // 若有自定义的定时/异步重绘逻辑,这里也要一并取消 CancelCustomDrawTasks(); } } protected override void OnAppearing() { base.OnAppearing(); // 返回页面时恢复渲染 if (!skglView.IsDisposed) { skglView.Resume(); } }方案2:替换为SKCanvasView
如果你的绘制逻辑不需要OpenGL硬件加速能力,直接将SKGLView替换为SKCanvasView即可。软件渲染的SKCanvasView没有原生GL资源的生命周期问题,不会出现这类崩溃,仅在复杂绘制场景下性能略低于SKGLView。方案3:增加绘制前校验
所有触发SKGLView重绘的逻辑前,先校验控件是否存活:void TriggerRedraw() { // 控件已销毁时直接跳过绘制 if (skglView.IsDisposed || skglView.Handle == IntPtr.Zero) return; skglView.InvalidateSurface(); }方案4:自定义iOS渲染器兜底
如果上述方案都无法解决,可在iOS平台自定义SKGLView的渲染器,在原生View即将销毁时清空所有待执行回调:[assembly: ExportRenderer(typeof(SKGLView), typeof(CustomSKGLViewRenderer))] namespace YourApp.iOS.Renderers { public class CustomSKGLViewRenderer : SKGLViewRenderer { protected override void Dispose(bool disposing) { if (disposing && Control != null) { // 清空所有待执行的异步任务 Control.Layer.RemoveAllAnimations(); NSRunLoop.Main.CancelPerformSelectors(Control); } base.Dispose(disposing); } } }
内容的提问来源于stack exchange,提问作者Junior Jiang
相关产品推荐
相关产品推荐

