gpt4 book ai didi

ios - Monotouch 和 catiledlayer

转载 作者:行者123 更新时间:2023-11-28 21:27:25 28 4
gpt4 key购买 nike

我的一个老问题与在 monotouch 中查看 pdf 文件有关(我设法完成了这个)。 Port of the iOS pdf viewer for xamarin

我的问题如下:如果我开始关闭和打开 pdf View (使用 catiledlayer 查看)非常快并且我的应用程序经常崩溃并显示:

在执行 native 代码时收到 SIGSEGV。这通常表明
单声道运行时或 native 库之一中的 fatal error
由您的应用程序使用。

在互联网上搜索了几天后,我发现了一篇帖子,内容大致如下:图像后台存储正在清理,这导致了错误。


编辑:好的,我得出的结论是我的应用程序正在清理内存并且我的指针正在变为空值。我调用了 Gc.Collect() 几次,这似乎是问题的根源。

我已经删除了对 GC.Collect() 的所有调用,并且我目前正在运行压力测试并将在我发现问题时进行更新。

在运行更多测试后,这是我发现的:

  • 错误似乎源自 TiledLayerDelegate : CALayerDelegate 类。

  • 仅当方法 Dispose from CALayerDelegate 被调用 时应用程序才会崩溃,将方法覆盖为空似乎可以防止应用程序崩溃。

  • 运行该应用程序似乎不再引起任何问题。很明显,CALayerDelegate 的 Dispose 方法出了点问题。

  • 最后发现:像猴子一样运行应用程序往往会使应用程序过热。我认为这是由于 pdf 页面的密集渲染(它们是大约 4,000 X 3,000 像素的巨大页面)

    protected override void Dispose (bool disposing)
    {
    try{
    view = null;
    GC.Collect (2);
    //base.Dispose (disposing);
    }catch(Exception e) {
    //System.Console.Write(e);
    }
    }

现在最重要的是,我只是想知道手机发热是否真的像我假设的那样只是 CPU 渲染工作表并且是正常的。有没有人知道如何最好地处理 Dispose 覆盖?

最后编辑:对于任何想要防止崩溃的人来说,这是我最后一个版本的图层 View 类的样子。

public class TiledPdfView : UIView {
CATiledLayer tiledLayer;

public TiledPdfView (CGRect frame, float scale)
: base (frame)
{
tiledLayer = Layer as CATiledLayer;
tiledLayer.LevelsOfDetail = 4; //4
tiledLayer.LevelsOfDetailBias = 4;//4
tiledLayer.TileSize = new CGSize (1024, 1024);
// here we still need to implement the delegate
tiledLayer.Delegate = new TiledLayerDelegate (this);
Scale = scale;

}

public CGPDFPage Page { get; set; }

public float Scale { get; set; }


public override void Draw (CGRect rect)
{
// empty (on purpose so the delegate will draw)
}


[Export ("layerClass")]
public static Class LayerClass ()
{
// instruct that we want a CATileLayer (not the default CALayer) for the Layer property
return new Class (typeof (CATiledLayer));
}

protected override void Dispose (bool disposing)
{
Cleanup ();
base.Dispose (disposing);
}

private void Cleanup ()
{
InvokeOnMainThread (() => {
tiledLayer.Delegate = null;
this.RemoveFromSuperview ();
this.tiledLayer.RemoveFromSuperLayer ();

});
}

最佳答案

Apple 的示例代码并不是很好。查看您的 tiled view 的来源我没有看到将层委托(delegate)设置为 nil 的地方。在底层,CATiledLayer 创建了一个队列来调用后台的分块渲染。这可能会导致竞争,解决此问题的一种方法是明确取消委托(delegate)。实验表明,这有时会阻塞,因此预计会有一些性能下降。是的,这是一个错误,你应该 file a feedback - 我几年前就这样做了。

我正在开发一个商业 PDF SDK(我们有一个非常流行的 Xamarin wrapper )并且我们在几年前离开了 CATiledLayer。这是一个相对简单的解决方案,但 PDF 的本质是渲染一个部分,必须遍历整个渲染树 - 找出屏幕上的内容和不显示的内容并不总是那么容易。 Apple 的渲染器在这方面做得还不错,性能也不错,但如果您渲染成一张图像,然后在用户滚动时四处移动/重新渲染,您将获得更好的性能。 (当然,这更棘手也更难正确地内存,尤其是在视网膜屏幕上。)

如果您没有时间离开 CATiledLayer,有些人会使用核选项并手动从 View 中删除层。参见例如this question了解更多详情。

关于ios - Monotouch 和 catiledlayer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37552309/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com