首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Monotouch和catiledlayer

Monotouch和catiledlayer
EN

Stack Overflow用户
提问于 2016-05-31 17:40:14
回答 1查看 93关注 0票数 0

我的一个老问题与单调查看pdf文件有关(我设法做到了这一点)。xamarin的iOS pdf查看器端口

我的问题如下:如果我开始关闭并打开一个pdf视图(用catiledlayer查看),并且我的应用程序经常会崩溃:

Got a SIGSEGV while executing native code. This usually indicates a fatal error in the mono runtime or one of the native libraries used by your application.

在互联网上搜索了几天之后,我发现一个帖子,上面写着:图像回店正在被清理,这导致了错误。

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

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

在运行了更多的测试之后,我发现:

  • 错误似乎起源于TiledLayerDelegate : CALayerDelegate类。
  • 该应用程序只有在方法Dispose from CALayerDelegate is called (将方法重写为空)时才崩溃,这似乎可以防止应用程序崩溃。
  • 运行该应用程序似乎不再引起任何问题。很明显,CALayerDelegate的处置方法确实出了问题。
  • 最后一项发现:像猴子一样运行应用程序会让应用程序升温一些。我想这是由于pdf页面的密集渲染(它们是巨大的页面--约4,000 x,000 px)。 保护覆盖base.Dispose (bool处理){ try{ view = null;GC.Collect (2);//base.disposed(处理);}catch(异常e) {//System.Console.W区(E);}}

现在最重要的是,我只是想知道手机发热是否真的像我认为的那样,只不过是CPU渲染床单,而且是正常的。有人对如何最好地处理Dispose覆盖有任何想法吗?

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

代码语言:javascript
复制
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 ();

        });
    }
EN

回答 1

Stack Overflow用户

发布于 2016-06-07 04:32:47

苹果公司的示例代码并不是很好。查看您的平铺视图的源,我没有看到您将层委托设置为零的位置。在遮罩下,CATiledLayer创建一个队列来调用背景中的平铺渲染。这可能导致种族竞争,而解决这一问题的一种方法就是显式地对委托进行起名。实验表明,这有时会阻塞,因此预期会出现一些性能下降。是的,这是一个错误,你应该提出反馈意见 --我几年前就这么做了。

我正在开发一个商业PDF (而且我们有一个非常流行的Xamarin包皮),我们几年前就离开了CATiledLayer。这是一个相对简单的解决方案,但PDF的本质是,要渲染一个部分,就必须遍历整个呈现树--找出屏幕上的内容和不存在的内容并不总是那么容易。苹果的渲染器在这方面做得还不错,性能也不错,但如果你渲染成一个图像,然后在用户滚动时将其移动/重新渲染,你会得到更好的效果。(当然,在记忆方面,尤其是在视网膜屏幕上,这会变得更加棘手和困难。)

如果你没有时间离开CATiledLayer,有些人会选择核选择,也会手动将图层从视图中移除。有关更多细节,请参见这个问题

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37552309

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档