【问题标题】:iOS app crashing while rendering webview layer using renderInContext: apiiOS应用程序在使用renderInContext渲染webview层时崩溃:api
【发布时间】:2014-01-07 12:11:05
【问题描述】:

我正在使用 UIWebView 从电子邮件中加载 ppt 文件,并在主线程的 do while 循环中使用 renderInContext: api 将 ppt 页面转换为图像。

当我加载少于 50 张幻灯片的小 ppt 文件时,它工作正常。当我加载 100 页 ppt 文档时,我的应用程序崩溃了。崩溃发生在第 83 次 renderInContext: API(从 UIWebview 渲染 UILayer)。

下面是我在 ARC 应用程序中使用的一段代码。

do
    {
        @autoreleasepool
        {
            NSLog(@"Image Index: %d",i);
            UIGraphicsBeginImageContext(CGSizeMake(768.0f, 576.0f));
            CGContextRef ctxCurrentGraphics = UIGraphicsGetCurrentContext();

            [webView.layer renderInContext:ctxCurrentGraphics];
            CGContextSetInterpolationQuality(ctxCurrentGraphics, kCGInterpolationHigh);
            CGContextSetRenderingIntent(ctxCurrentGraphics, kCGRenderingIntentDefault);
            UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

            UIGraphicsEndImageContext();

            /******* Each snap shot been inserted to db before new snapshot created ********/

            if (image != nil)
            {
                [[DataManager instance] insertImportedImageToDb:image importFileName:filename ...];
                slideID++;
                seqID++;
            }

            [webView.scrollView scrollRectToVisible:CGRectMake(0.0f, (i * 581.3) , webView.bounds.size.width, webView.bounds.size.height) animated:NO];
            scrolloffset = scrolloffset + 581.3;

            i++;

            /***** check if ppt contains only one page ****/
            if (webView.scrollView.contentSize.height == 1004.0 || webView.scrollView.contentSize.height == 1005.0)
            {
                break;
            }

            image = nil;
        }
    }
    while (scrolloffset <= webView.scrollView.contentSize.height);

应用程序仅在设备 (iOS6) 上崩溃。我尝试了在 Stack Overflow 中找到的所有替代方法,例如清除上下文、@autoreleasepool 的使用等。

有什么方法可以优化内存使用,或者有什么替代 renderInContext: API 的方法,似乎这个 api 有内存泄漏?

Edit1:大多数时候应用程序收到“内存不足警告”,但我两次看到以下崩溃日志:

Last Exception Backtrace:
0   CoreFoundation                  0x316aa29e 0x315e8000 + 795294
1   libobjc.A.dylib                 0x3954e97a 0x39546000 + 35194
2   CoreFoundation                  0x316aa1c0 0x315e8000 + 795072
3   UIKit                           0x3389dd5a 0x334af000 + 4123994
4   MyApplication                   0x000c590c 0xa3000 + 141580
5   MyApplication                   0x000c4d26 0xa3000 + 138534
6   Foundation                      0x31fc1f4e 0x31f10000 + 728910
7   CoreFoundation                  0x3167f5da 0x315e8000 + 619994
8   CoreFoundation                  0x3167f28c 0x315e8000 + 619148
9   CoreFoundation                  0x3167defc 0x315e8000 + 614140
10  CoreFoundation                  0x315f0eb8 0x315e8000 + 36536
11  CoreFoundation                  0x315f0d44 0x315e8000 + 36164
12  GraphicsServices                0x351a52e6 0x351a0000 + 21222
13  UIKit                           0x335062fc 0x334af000 + 357116
14  MyApplication               0x000a8c60 0xa3000 + 23648
15  libdyld.dylib                   0x39985b1c 0x39984000 + 6940

【问题讨论】:

  • 用错误详情更新我的问题。而且大多数时候应用都会收到“内存不足警告”。

标签: ipad ios6 uiwebview core-graphics calayer


【解决方案1】:

问题的根本原因是从 webview 递归捕获图像,其中 renderInContext: 用于捕获。

问题仅在 83 次图像捕获(for 循环中的第 84 次迭代)之后发生,因此我觉得存在巨大的内存泄漏。

不确定这是针对此问题的乐观解决方案。但我设法使用以下步骤解决了..

(1) renderInContext: 没有立即释放图形上下文,因此会累积内存,因此会发出低内存警告。我尝试的解决方案是将整个函数保留在@autorelease 下,并将捕获下一张图像延迟 1 毫秒,这在性能方面可以忽略不计。

(2) 避免使用 forloop 并将图像存储在可变数组中。这也节省了一些内存。这也减少了堆内存的使用。

希望这对某人有所帮助..

【讨论】:

    【解决方案2】:

    我认为原因是 API:renderInContext 没有立即释放图形上下文,因此内存不足警告。当多次出现内存不足警告时,系统将终止您的程序,而不是崩溃。

    我设法通过以下步骤解决:

    //render
    [selectView.layer renderInContext:UIGraphicsGetCurrentContext()];
    
    //clear the cache 
    //UIWebview
    if ([selectView isKindOfClass:[UIWebView class]])
    {
        [(UIWebView *)selectView loadHTMLString:nil baseURL:nil];
    //others
    }else
    {
         selectView.layer.contents = (id)nil;
    }
    
    Hope this helps somebody..
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-16
      • 1970-01-01
      • 2012-09-22
      • 1970-01-01
      • 2019-12-05
      • 1970-01-01
      相关资源
      最近更新 更多