drawViewHierarchyInRect与renderInContext的预期性能是什么

时间:2015-11-08 09:01:05

标签: ios objective-c uiimage screenshot

浏览了SO上的所有相关问题后,我理解drawViewHierarchyInRect应该比renderInContext快得多,但这不是我所看到的。

这是我的带有时间分析的快照功能:

- (UIImage *)screenshot
{
    UIScreen *mainScreen = [UIScreen mainScreen];
    CGSize imageSize = mainScreen.bounds.size;
    if (&UIGraphicsBeginImageContextWithOptions != NULL) {
        UIGraphicsBeginImageContextWithOptions(imageSize, NO, 1);
    } else {
        UIGraphicsBeginImageContext(imageSize);
    }

    CGContextRef context = UIGraphicsGetCurrentContext();

    NSArray *windows = [[UIApplication sharedApplication] windows];
    for (UIWindow *window in windows) {
        if (![window respondsToSelector:@selector(screen)] || window.screen == mainScreen) {
            NSDate *methodStart = [NSDate date];

//            [window.layer renderInContext:context];
            [window drawViewHierarchyInRect:window.bounds afterScreenUpdates:NO];

            NSDate *methodFinish = [NSDate date];
            NSTimeInterval executionTime = [methodFinish timeIntervalSinceDate:methodStart];
            NSLog(@"executionTime = %f", executionTime);
        }
    }

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return image;
}

使用IOS 9.0在iPad Air上进行测试 作为测试应用程序,我使用的是UIKitCatalog应用程序this very helpful thread

该应用显示2个窗口:

<UIWindow: 0x134e4d8f0; frame = (0 0; 768 1024); gestureRecognizers = <NSArray: 0x134e27740>; layer = <UIWindowLayer: 0x134e4d130>>,
<UITextEffectsWindow: 0x134e6a3a0; frame = (0 0; 768 1024); opaque = NO; autoresize = W+H; layer = <UIWindowLayer: 0x134e6aba0>>

使用drawViewHierarchyInRect会在两个窗口的任何上产生 0.078s renderInContext在主窗口上产生 0.045s ,在UITextEffectsWindow上产生一些较小的(0.000028s)时间。

  1. 为什么drawViewHierarchyInRect比renderInContext慢,是不是应该更快

  2. 两个(78毫秒,45毫秒)对于以任何合适的帧速率录制屏幕视频都是不可接受的。似乎某些事情是非常错误的,它应该更快。

  3. [window.layer renderInContext ...]导致截图混乱且不准确,我试过[window.layer.presentationLayer renderInContext ...],但这导致应用程序崩溃,我可以'找到原因。

  4. 我很感激任何帮助,我要做的就是以最高的帧速率录制屏幕视频,到目前为止,我得到的结果没有意义,或者我可能做了一些非常错误的事情

    由于

1 个答案:

答案 0 :(得分:1)

你问:

  
      
  1. 为什么drawViewHierarchyInRectrenderInContext慢,是不是应该更快?
  2.   

这完全取决于你捕获的内容。例如,使用一堆简单的UIView子视图捕获视图,我看不出明显的差异。当捕获具有复杂UIImageView的视图(例如,非常高分辨率的图像)时,我发现在极端情况下drawViewHierarchyInRect可以大约快10倍。我发现后者的性能差异与Apple在Implementing Engaging UI in iOS中声称的相似,其中的示例包含了一堆图像视图。

我从这些诊断推断drawViewHierarchyInRect针对具有UIImageView个对象的屏幕快照进行了优化。因此,虽然它可能针对特定情况进行了高度优化,但我并不完全惊讶可能存在不会产生相同结果的情况。

  
      
  1. 两者(78ms,45ms)对于以任何合适的帧速率录制屏幕视频是不可接受的。似乎某些事情是非常错误的,它应该更快。
  2.   

这些不是专为视频捕捉而设计的,所以我不确定你的意思是“出了什么问题。”为什么你说“它应该快得多”?

  
      
  1. [window.layer renderInContext ...]导致截图混乱且不准确......
  2.   

您应该编辑您的问题以包含屏幕快照,以向我们展示您的意思。

  

...我试过[window.layer.presentationLayer renderInContext ...],但是这会导致应用程序崩溃,我找不到原因。

presentationLayer方法用于获取当前演示状态的副本(通常用于查询动画中期),但它不是您通常与之交互的图层。