[ios]随着时间的推移减慢 CGLayer 绘图

标签: ios Objective-C
发布时间: 2017/3/21 22:45:23
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

任何人都能解释为什么重绘屏幕外的 CGLayer 到会呈现随着时间的推移慢下来吗?让我告诉你测试我创建来说明问题。

@implementation DrawView


- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        //setup frame rate monitoring
        fps = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 100, 20)];
        fps.textColor = [UIColor whiteColor];
        fps.font = [UIFont boldSystemFontOfSize:15];
        fps.text = @"0 fps";
        [self addSubview:fps];
        frames = 0;
        lastRecord = [NSDate timeIntervalSinceReferenceDate];

        //create a cglayer and draw the background graphic to it
        CGContextRef context = UIGraphicsGetCurrentContext();
        cacheLayer = CGLayerCreateWithContext(context, self.bounds.size, NULL);

        CGImageRef background = [[UIImage imageNamed:@"background.jpg"] CGImage];
        CGContextRef cacheContext = CGLayerGetContext(cacheLayer);
        CGContextDrawImage(cacheContext, CGRectMake(0, 0, 768, 1024), background);

        //initialize cgimage stamp
        stamp = [[UIImage imageNamed:@"stamp.png"] CGImage];
        stampTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/60 target:self selector:@selector(stamp) userInfo:nil repeats:YES];
    }
    return self;
}

- (void) stamp {
    //calculate fps
    NSTimeInterval interval = [NSDate timeIntervalSinceReferenceDate];
    NSTimeInterval diff = interval-lastRecord;
    if (diff > 1.0) {
        float rate = frames/diff;
        frames = 0;
        lastRecord = [NSDate timeIntervalSinceReferenceDate];
        fps.text = [NSString stringWithFormat:@"%0.1f fps", rate];
    }
    //stamp the offscreen cglayer with the cgimage graphic
    CGRect stampRect = CGRectMake(0, 0, 200, 200);
    CGContextRef cacheContext = CGLayerGetContext(cacheLayer);
    CGContextDrawImage(cacheContext, stampRect, stamp);
    [self setNeedsDisplayInRect:stampRect];
}

- (void)drawRect:(CGRect)dirtyRect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextDrawLayerInRect(context, self.bounds, cacheLayer);
    frames++;
}

当我运行此测试在 ipad 模拟器或设备启动 40 帧每秒和 10 秒,直到它运行在喜欢 3 fps,当然以恒定速率下降。为什么是这种情况发生?这不应该运行在恒定的帧率?什么样的解决方案将允许我 '邮票' 形象遍又一遍同时保持恒定的帧率?

解决方法 1:

你的问题是使用空的上下文创建你的图层。UIGraphicsGetCurrentContext()的有效期只画循环过程中。你称之为画循环外如此它为 NULL,如此层无法缓存任何东西。它仍然让我很惊讶这多么严重损坏客户性能随着时间的推移。我怀疑可能有一个错误在 CoreGraphics;你认为这只会缓慢;不"过放缓"。但尽管如此,它没有设计这种方式工作。

如果你创建一个位图上下文和使用为你的图层,你会得到你 60 fps。你不需要在这里放弃 CGLayer。

我要回到 60 fps 所做的一切是替换此︰

CGContextRef context = UIGraphicsGetCurrentContext();

为此︰

CGContextRef context = CreateBitmapContext(self.bounds.size);

其中 CreateBitmapContext() 是一个函数,返回同一件事你 createBitmapContext 设置。

官方微信
官方QQ群
31647020