MonoTouch CoreGraphics与CGPDFDocument和CGPDFPage有关的PDF内存问题

我已经和MonoTouch合作了3个星期,一切都很顺利,直到我不得不在我的应用程序中显示PDF。

使用Apple的Quartz 2D编程指南我设法显示PDF。

问题是,应用程序内存不足。 我试图在CGPDFDocument和CGPDFPage对象上使用Dispose()方法,但后来我收到此错误:

Stacktrace: at (wrapper managed-to-native) MonoTouch.CoreGraphics.CGPDFPage.CGPDFPageRelease (intptr)  at MonoTouch.CoreGraphics.CGPDFPage.Dispose (bool)  at MonoTouch.CoreGraphics.CGPDFPage.Finalize ()  at (wrapper runtime-invoke) object.runtime_invoke_virtual_void__this__ (object,intptr,intptr,intptr)  Native stacktrace: 0 FlapMag1 0x00037514 mono_handle_native_sigsegv + 412 1 FlapMag1 0x0000c010 mono_sigsegv_signal_handler + 348 2 libSystem.B.dylib 0x339927f3 _sigtramp + 34 3 libCGVolute.A.dylib 0x31c83d88 CPModelRelease + 24 4 libCGVolute.A.dylib 0x31c84ad4 model_release + 56 5 CoreGraphics 0x3113ced8 pdf_page_finalize + 68 6 CoreFoundation 0x3388fae9 _CFRelease + 168 7 CoreFoundation 0x3388f9c7 CFRelease + 66 8 CoreGraphics 0x3113ce90 CGPDFPageRelease + 20 9 FlapMag1 0x00248cc0 wrapper_managed_to_native_MonoTouch_CoreGraphics_CGPDFPage_CGPDFPageRelease_intptr + 64 * Assertion: should not be reached at ../../../../mono/mini/mini-darwin.c:258 

这慢慢让我发疯,因为我尝试了我能想到的一切。

在Apple的例子中有CGPDFDocumentRelease和CGPDFPageRelease,但MonoTouch中缺少这些。 因此我认为MT会自动管理这些对象,但显然它没有或者它是错误的。

即使我没有弄乱CGPDF对象的Dispose(),当我从superview中删除包含PDF的视图时,会发生上述错误。

有人能够在MonoTouch中使用PDF吗?

提前致谢。

更新:
我使用相同的PDF测试了Obj-C中的PDF绘图,发现当我不调用CGPDFDocumentRelease()时,内存消耗与MonoTouch中的内存消耗速度相同。 通过在Obj-C中调用CGPDFDocumentRelease(),内存消耗是正常的。
因此我认为MonoTouch确实没有释放CGPDFDocument和CGPDFPage对象,当我尝试手动或间接释放它们时(通过删除包含它们的视图),我得到了上述错误。

这非常耗费时间,现在是一个真正的可能性,我必须重写Obj-C中的代码… F $#k !!

另一个更新:
我仍然无法解密为什么我得到与发布有关的错误,但是我制作了一个MonoTouch和一个XCode项目,其中两者基本上都是一样的:绘制PDF。
我比较了Activity Monitor中两者的内存使用情况,发现虽然MonoTouch应用程序不断增加内存使用量,但XCode应用程序却没有。 我甚至在MonoTouch中的CGPDFDocument对象上调用Dispose(),但内存消耗仍然增加。
这两款应用程序都没有因发布相关错误而崩溃,但真的让人担心MonoTouch应用程序中的内存使用量会大得多……

我认为我的问题出在其他地方,但我来到这里是因为我的主应用程序在内存消耗过高后崩溃了,我似乎无法找到一种方法来降低它,因为我得到了这些烦人的发布错误。

和另一个更新:
在视图的Draw()方法中绘制pdf的代码:

 CGContext context = UIGraphics.GetCurrentContext(); context.SaveState(); CGPDFDocument pdfDoc = CGPDFDocument.FromUrl(_pdfFileUrl); if(pdfDoc.Pages >= 1) { CGPDFPage pdfPage = pdfDoc.GetPage(1); context.ScaleCTM(SCALE.Width, SCALE.Height); // the PDFRectangle is the media box rect of the page, which is hardcoded // for now context.TranslateCTM(-this.PDFRectangle.X, -this.PDFRectangle.Height - this.PDFRectangle.Y); context.DrawPDFPage(pdfPage); } pdfDoc.Dispose(); context.RestoreState(); 

这是由MonoTouch Alpha中的一个错误引起的,该错误将在1.9.3版本中修复

上面的堆栈跟踪显示PDF版本代码是从终结器线程调用的,而不是直接从Dispose调用的。

你能不能给我一个展示问题的测试用例? 一旦我们有了测试用例,我们应该能够在几个小时内为您提供修复或解决方法。

Interesting Posts