Проблемы памяти MonoTouch CoreGraphics PDF с CGPDFDocument и CGPDFPage

Я работаю с MonoTouch уже 3 недели, и все шло отлично, пока мне не пришлось отображать PDF-файлы в своем приложении.

Используя Руководство по программированию Quartz 2D Мне удалось отобразить PDF.

Проблема в том, что приложению не хватает памяти. Я пытался использовать методы Dispose() для объектов CGPDFDocument и CGPDFPage, но затем получаю эту ошибку:

Stacktrace:

  at (wrapper managed-to-native) MonoTouch.CoreGraphics.CGPDFPage.CGPDFPageRelease (intptr) <0xffffffff>
  at MonoTouch.CoreGraphics.CGPDFPage.Dispose (bool) <0x00044>
  at MonoTouch.CoreGraphics.CGPDFPage.Finalize () <0x0002b>
  at (wrapper runtime-invoke) object.runtime_invoke_virtual_void__this__ (object,intptr,intptr,intptr) <0x0007b>

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 управляет этими объектами автоматически, но, видимо, это не так или он глючит.

Даже когда я не связываюсь с Dispose() объекта CGPDF, возникает вышеуказанная ошибка, когда я удаляю представление, содержащее PDF, из суперпредставления.

Кто-нибудь смог работать с PDF-файлами в MonoTouch?

Заранее спасибо.

ОБНОВЛЕНИЕ:
Я протестировал рисование PDF в Obj-C с теми же PDF-файлами и обнаружил, что когда я не вызываю CGPDFDocumentRelease(), потребление памяти имеет такую ​​же тенденцию к быстрому увеличению, как и в MonoTouch. При вызове CGPDFDocumentRelease() в Obj-C потребление памяти является нормальным.
Поэтому я думаю, что MonoTouch действительно не освобождает объекты CGPDFDocument и CGPDFPage, и когда я пытаюсь освободить их вручную или косвенно (путем удаления представлений которые содержат их), я получаю вышеуказанную ошибку.

Это полный отстой, и сейчас вполне возможно, что мне придется переписать код в Obj-C... F$#k!!

ДРУГОЕ ОБНОВЛЕНИЕ:
Я до сих пор не могу понять, почему я получаю ошибки, связанные с выпуском, но я сделал проект MonoTouch и XCode, где оба делают одно и то же: рисуют PDF-файлы.
Я сравнил память. использование обоих в мониторе активности и обнаружил, что, хотя приложение MonoTouch постоянно увеличивает использование памяти, приложение XCode этого не делает. Я даже вызываю Dispose() для объекта CGPDFDocument в MonoTouch, но потребление памяти все равно увеличивается.
Ни одно из приложений не вылетает из-за ошибки, связанной с выпуском, но действительно беспокоит то, что использование памяти в приложении MonoTouch значительно больше. .

Я полагаю, что моя проблема заключается в другом, но я попал сюда, потому что мое основное приложение разбилось после того, как потребление памяти стало слишком высоким, и я не могу найти способ снизить его, потому что я получаю эти раздражающие ошибки выпуска.

И ЕЩЕ ОДНО ОБНОВЛЕНИЕ:
Код, рисующий PDF-файл в методе Draw() представления:

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();

person Community    schedule 18.02.2010    source источник


Ответы (2)


Это было вызвано ошибкой в ​​MonoTouch Alpha, которая будет исправлена ​​в версии 1.9.3.

person Community    schedule 22.02.2010
comment
В чем преимущество/недостаток использования Quartz для отображения PDF по сравнению с UIDocumentInteractionController? Я видел, как используются оба. Я спрашиваю, что bc UIDocumentInteractionController не видит, чтобы подчиняться опции отказа от печати PDF-файлов, и все равно разрешает печать, поэтому я ищу другой способ их просмотра. - person Krumelur; 14.01.2011

Приведенная выше трассировка стека показывает, что код выпуска PDF был вызван из потока финализатора, а не напрямую из Dispose.

Не могли бы вы предоставить мне тестовый пример, демонстрирующий проблему? Как только у нас будет тестовый пример, мы сможем предоставить вам исправление или обходной путь через пару часов.

person Community    schedule 18.02.2010
comment
Спасибо за быстрый ответ. В основном мое приложение создает представление для каждого PDF-файла, потому что каждый PDF-файл содержит одну страницу. Пользователь может просматривать отдельные PDF-файлы как один непрерывный PDF-файл. Мы должны были сделать это таким образом, потому что в противном случае приложению пришлось бы сначала загружать весь PDF-файл. Проблема выпуска возникает, когда я удаляю ненужные представления из контейнера представлений. Я напишу метод рисования в вопросе. Но в основном он загружает pdf-документ, получает страницу, рисует страницу и затем удаляет документ (как написано в примере Apple). - person Alpár; 19.02.2010
comment
Привет. Я переписал свой вид чертежа в формате PDF на основе вашего примера на git и сузил свою проблему до метода Dispose() CGPDFDocument. Каждый раз, когда я вызываю Dispose() в своем представлении (которое также реализует интерфейс IDisposable), в нем вызывается Dispose() документа pdf, приложение вылетает с этой ошибкой: (...) at (wrapper manage-to -native) MonoTouch.CoreGraphics.CGPDFDocument.CGPDFDocumentRelease (intptr) ‹0xffffffff› в MonoTouch.CoreGraphics.CGPDFDocument.Dispose (bool) ‹0x00044› в MonoTouch.CoreGraphics.CGPDFDocument.Dispose () ‹0x00027› (...) - person Alpár; 19.02.2010
comment
Спасибо за отзыв, теперь у нас есть исправление, и оно появится в нашем следующем обновлении. - person miguel.de.icaza; 23.02.2010