UIGraphicsBeginPDFPageWithInfo中的iOS崩溃

时间:2014-08-05 00:56:53

标签: ios crash uikit

上下文:Xcode 5,iOS 7.1。

我有一些生成PDF的代码,可以选择在其中嵌入现有的PDF,使用PSPDFKit渲染现有PDF的页面。 99%的时间,代码工作正常;但是在可重现的1%的时间里,我遇到了崩溃(exc_bad_access)。我无法解释当我重现崩溃时的不同之处 - 通常我需要让应用程序生成PDF N次(今天N = 5,其他天N = 2)然后崩溃发生。

代码只是在循环中进行这两个调用:

CGSize pageSize = CGSizeMake(612*3, 792*3);
{
    UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, size.width, size.height), nil);

    NSError *error = nil;

     [pdfDoc renderPage:innerPageNum
                    inContext:UIGraphicsGetCurrentContext();
                      withSize:size
          clippedToRect:CGRectZero
        withAnnotations:nil
                      options:nil
                         error:&error];
}

偶尔它会在UIGraphicsBeginPDFPageWithInfo中崩溃,总是在汇编代码中的下面。有没有人见过这样的东西或有调试的线索?无法访问UIKit源,我非常无能为力。

CoreGraphics`CGPDFSecurityHandlerIsUnlocked:

0x41559ff:  pushl  %ebp
0x4155a00:  movl   %esp, %ebp
0x4155a02:  xorb   %al, %al
0x4155a04:  movl   0x8(%ebp), %ecx
0x4155a07:  testl  %ecx, %ecx
0x4155a09:  je     0x4155a12                 ; CGPDFSecurityHandlerIsUnlocked + 19
0x4155a0b:  cmpb   $0x0, 0x7c(%ecx)   <<< Thread 1: EXC_BAD_ACCESS (code=2, address=0xde)
0x4155a0f:  setne  %al
0x4155a12:  movzbl %al, %eax
0x4155a15:  popl   %ebp
0x4155a16:  ret  

如果我可以附加一个图像来显示堆栈跟踪,我相信会显示该函数最终达到了此调用深度的21个隐藏堆栈级别:

UIKit`UIGraphicsBeginPDFPageWithInfo:

0x431914f:  pushl  %ebp
0x4319150:  movl   %esp, %ebp
0x4319152:  pushl  %ebx
0x4319153:  pushl  %edi
0x4319154:  pushl  %esi
0x4319155:  subl   $0x5c, %esp
0x4319158:  calll  0x431915d                 ; UIGraphicsBeginPDFPageWithInfo + 14
0x431915d:  popl   %esi
0x431915e:  movl   $0x2, %ecx
0x4319163:  calll  0x4318cb7                 ; GetCurrentContext
0x4319168:  movl   %eax, %edi
0x431916a:  movl   $0x2, %ecx
0x431916f:  calll  0x4318ce1                 ; GetCurrentContextAuxInfo
0x4319174:  testl  %edi, %edi
0x4319176:  je     0x43192cb                 ; UIGraphicsBeginPDFPageWithInfo + 380
0x431917c:  testl  %eax, %eax
0x431917e:  je     0x43192cb                 ; UIGraphicsBeginPDFPageWithInfo + 380
0x4319184:  movl   $0x2, %ecx
0x4319189:  calll  0x4318ce1                 ; GetCurrentContextAuxInfo
0x431918e:  testl  %eax, %eax
0x4319190:  je     0x43192bd                 ; UIGraphicsBeginPDFPageWithInfo + 366
0x4319196:  cmpb   $0x0, 0x20(%eax)
0x431919a:  movl   %eax, %ebx
0x431919c:  je     0x43191a6                 ; UIGraphicsBeginPDFPageWithInfo + 87
0x431919e:  movl   %edi, (%esp)
0x43191a1:  calll  0x4aaa848                 ; symbol stub for: CGPDFContextEndPage
0x43191a6:  leal   0x8(%ebp), %eax          <<< Thread 1: EXC_BAD_ACCESS (code=2, address=0xde)

2 个答案:

答案 0 :(得分:1)

我不确定这是否完全相同,但我在这里回答了类似的问题:UIGraphicsBeginPDFPage() randomly crashes on 64bit devices (CGPDFSecurityManagerCreateDecryptor ())

解决方案的要点是延迟调用目标PDF中使用的任何PDF CGPDFDocumentRelease,直到目标PDF被UIGraphicsEndPDFContext关闭为止。对我而言,遗憾的是,即使我能够这样做,但是在过程结束之前不会释放一些记忆,但它似乎确实有效。

答案 1 :(得分:0)

对我来说,这是在以下情况下,我也尝试使用CGContextRelease释放它(又名currentContext)时发生的:

UIGraphicsEndPDFContext();
CGContextRelease(pdfContext);//<-comment this out to solve

原来我只需要UIGraphicsEndPDFContext();,由于某种原因(我只能假定涉及异步调用),甚至在调用EndPDFContext之后再调用CGContextRelease,仍然会在EndPDFContext行上引起EXC_BAD_ACCESS。