我正在使用UIWebView从电子邮件加载ppt文件,并在主线程的do while循环中使用renderInContext:api将ppt页面转换为图像。
当我加载少于50张幻灯片的小ppt文件时,它工作正常。当我加载100页ppt文档时,我的应用程序崩溃了。崩溃发生在renderInContext:API(从UIWebview渲染UILayer)的第83次。
以下是我在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:大部分时间收到应用程序&#39;低内存警告&#39;但两次我看到下面的崩溃日志:
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
答案 0 :(得分:0)
问题的根本原因是从webview递归捕获图像,其中renderInContext:用于捕获。
问题发生在83次图像捕获之后(for循环中的第84次迭代),因此我觉得存在巨大的内存泄漏。
不确定这是解决此问题的乐观方法。但我设法使用以下步骤解决..
(1)renderInContext:不会立即释放图形上下文,因此会累积内存,从而导致内存不足警告。我试过的解决方案是将整个函数保留在@autorelease下,只是延迟捕获下一个图像1毫秒,这在性能方面可以忽略不计。
(2)避免使用forloop并将图像存储在可变阵列中。这也节省了一些记忆。这也减少了堆内存使用量。
希望这有助于某人......
答案 1 :(得分:0)
我认为原因是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..