我的一个老问题是与在monotouch中查看pdf文件有关(我设法做到了)。 Port of the iOS pdf viewer for xamarin
我的问题如下:如果我开始非常快地关闭并打开pdf视图(带有catiledlayer的视图),并且我的应用经常崩溃,则出现:Got a SIGSEGV while executing native code. This usually indicatesa fatal error in the mono runtime or one of the native librariesused by your application.
在互联网上研究了几天后,我发现了一条帖子,内容大致如下:图像后备存储正在清理中,这导致了错误。
编辑:
好的,我得出的结论是我的应用程序正在清理内存,并且指针变为空值。我多次调用Gc.Collect(),这似乎是问题的根源。
我已经删除了对GC.Collect()的所有调用,并且当前正在运行压力测试,并且在确定问题时会进行更新。
运行更多测试后,我发现了这一点:
该错误似乎在TiledLayerDelegate : CALayerDelegate
类中引起。
仅当方法Dispose from CALayerDelegate is called
将该方法覆盖为空时,该应用程序才会崩溃,以防止该应用程序崩溃。
运行该应用程序似乎再也不会造成任何问题。显然,CALayerDelegate的Dispose方法确实出了问题。
最后发现:像猴子一样运行应用程序会使应用程序升温。我认为这是由于pdf页面的密集渲染(它们是大约4,000 X 3,000 pxs的大片)
protected override void Dispose (bool disposing)
{
try{
view = null;
GC.Collect (2);
//base.Dispose (disposing);
}catch(Exception e) {
//System.Console.Write(e);
}
}
现在,最重要的是,我只是想知道电话是否真的在升温,因为我只假设CPU渲染工作表是正常的。是否有人对如何最好地处理
Dispose
替代有任何想法?上次编辑:对于希望防止崩溃的任何人,这就是我的最新版本的图层视图类。
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 ();
});
}
最佳答案
苹果公司的示例代码并不是很好。查看您的tiled view的源,看不到将图层委托设置为nil的地方。在后台,CATiledLayer
创建一个队列以在后台调用平铺渲染。这可能会导致比赛,解决此问题的一种方法是显式地使委托变小。实验表明,这有时会阻止,因此会导致性能下降。是的,这是一个错误,您应该file a radar-我几年前就这样做了。
我正在开发商业PDF SDK(我们有一个非常受欢迎的Xamarin wrapper),几年前我们离开了CATiledLayer
。这是一个相对简单的解决方案,但是PDF的本质是渲染一部分,必须遍历整个渲染树-找出屏幕上的内容和不显示的内容并不总是那么容易。 Apple的渲染器在此方面做得不错,性能还可以,但是如果渲染到一张图像中,然后随着用户滚动移动/重新渲染,您将获得更好的性能。 (当然,这对内存来说更棘手,更难解决,尤其是在视网膜屏幕上。)
如果您没有时间离开CATiledLayer
,则有些人会选择使用core选项,并手动从视图中删除该层。参见例如this question有关更多详细信息。
关于ios - Monotouch和Catiledlayer,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37552309/