gpt4 book ai didi

ios - setNeedsDisplayInRect 在 drawLayer :inContext: 期间调用

转载 作者:可可西里 更新时间:2023-11-01 05:00:34 32 4
gpt4 key购买 nike

我在我的应用程序中使用了 CATiledLayer,因此,该层的绘制是在后台线程中完成的。也就是说,我的委托(delegate)的 drawLayer:inContext: 方法是从后台线程调用的。用于使 CATiledLayer 的部分无效的 setNeedsDisplayInRect 始终从主线程调用。

因为是独立的线程,所以偶尔会出现后台线程在drawLayer:inContext方法中调用setNeedsDisplayInRect的情况。我注意到在那种情况下 setNeedsDisplayInRect 被忽略了(drawLayer:inContext 没有被再次调用)。

我已经记录了一个 bug to Apple ,因为我认为那是不正确的。但是我很难弄清楚如何解决这种情况。你有什么好主意吗?

编辑:

我使用以下代码测试了 Stanislaw 的回答:

- (void) setNeedsDisplayInRect:(CGRect)rect
{
NSLog(@"setNeedsDisplayInRect:%@", NSStringFromCGRect(rect));
[super setNeedsDisplayInRect:rect];
}

- (void) drawLayer:(CALayer *)layer inContext:(CGContextRef)gc
{
CGRect bounds = CGContextGetClipBoundingBox(gc);
NSLog(@"drawLayer:inContext: bounds=%@", NSStringFromCGRect(bounds));

dispatch_async(dispatch_get_current_queue(), ^{
[self setNeedsDisplayInRect:bounds];
});

CGContextSetFillColorWithColor(gc, testColor.CGColor);
CGContextFillRect(gc, bounds);
sleep(0.2); // simulate the time it takes to draw complicated graphics
NSLog(@"end drawLayer:inContext: bounds=%@", NSStringFromCGRect(bounds));
}

如前所述,代码确实会导致绘图无限期地重复,但有时在 setNeedsDisplayInRect: 和相应的 drawLayer:inContext: 之间有长达 5 秒的延迟,在此期间没有其他任何事情发生。请参阅下面的日志作为示例。请注意不规则的行为:在第一秒内,一些瓦片被重绘多次,而另一些只重绘一次。然后暂停 5 秒,然后循环重新开始。

这是在IOS6.0的模拟器上测试的(我选择那个版本,因为早期版本有另一个bug在6.0中被修复:他们有时会绘制相同的瓷砖两次)。

2012-10-27 15:51:38.771 TiledLayerTest[39934:15a13] drawLayer:inContext: bounds={{0, 300}, {300, 180}}
2012-10-27 15:51:38.774 TiledLayerTest[39934:15a13] end drawLayer:inContext: bounds={{0, 300}, {300, 180}}
2012-10-27 15:51:38.774 TiledLayerTest[39934:1570f] drawLayer:inContext: bounds={{300, 0}, {20, 300}}
2012-10-27 15:51:38.776 TiledLayerTest[39934:1570f] end drawLayer:inContext: bounds={{300, 0}, {20, 300}}
2012-10-27 15:51:38.776 TiledLayerTest[39934:1630b] setNeedsDisplayInRect:{{0, 300}, {300, 180}}
2012-10-27 15:51:38.777 TiledLayerTest[39934:1540f] setNeedsDisplayInRect:{{300, 0}, {20, 300}}
2012-10-27 15:51:38.780 TiledLayerTest[39934:15a13] drawLayer:inContext: bounds={{300, 0}, {20, 300}}
2012-10-27 15:51:38.781 TiledLayerTest[39934:15a13] end drawLayer:inContext: bounds={{300, 0}, {20, 300}}
2012-10-27 15:51:38.782 TiledLayerTest[39934:1540f] setNeedsDisplayInRect:{{300, 0}, {20, 300}}
2012-10-27 15:51:38.789 TiledLayerTest[39934:1570f] drawLayer:inContext: bounds={{0, 0}, {300, 300}}
2012-10-27 15:51:38.791 TiledLayerTest[39934:15a13] drawLayer:inContext: bounds={{300, 300}, {20, 180}}
2012-10-27 15:51:38.792 TiledLayerTest[39934:15a13] end drawLayer:inContext: bounds={{300, 300}, {20, 180}}
2012-10-27 15:51:38.793 TiledLayerTest[39934:1570f] end drawLayer:inContext: bounds={{0, 0}, {300, 300}}
2012-10-27 15:51:38.795 TiledLayerTest[39934:1540f] setNeedsDisplayInRect:{{0, 0}, {300, 300}}
2012-10-27 15:51:38.795 TiledLayerTest[39934:1540f] setNeedsDisplayInRect:{{300, 300}, {20, 180}}
2012-10-27 15:51:38.798 TiledLayerTest[39934:15a13] drawLayer:inContext: bounds={{0, 0}, {300, 300}}
2012-10-27 15:51:38.800 TiledLayerTest[39934:15a13] end drawLayer:inContext: bounds={{0, 0}, {300, 300}}
2012-10-27 15:51:38.802 TiledLayerTest[39934:1630b] setNeedsDisplayInRect:{{0, 0}, {300, 300}}
2012-10-27 15:51:38.806 TiledLayerTest[39934:1570f] drawLayer:inContext: bounds={{0, 300}, {300, 180}}
2012-10-27 15:51:38.808 TiledLayerTest[39934:1630b] setNeedsDisplayInRect:{{0, 300}, {300, 180}}
2012-10-27 15:51:38.809 TiledLayerTest[39934:1570f] end drawLayer:inContext: bounds={{0, 300}, {300, 180}}
2012-10-27 15:51:38.813 TiledLayerTest[39934:15a13] drawLayer:inContext: bounds={{0, 300}, {300, 180}}
2012-10-27 15:51:38.816 TiledLayerTest[39934:1630b] setNeedsDisplayInRect:{{0, 300}, {300, 180}}
2012-10-27 15:51:38.816 TiledLayerTest[39934:15a13] end drawLayer:inContext: bounds={{0, 300}, {300, 180}}
2012-10-27 15:51:43.774 TiledLayerTest[39934:1540f] drawLayer:inContext: bounds={{0, 300}, {300, 180}}
2012-10-27 15:51:43.776 TiledLayerTest[39934:1540f] end drawLayer:inContext: bounds={{0, 300}, {300, 180}}
2012-10-27 15:51:43.776 TiledLayerTest[39934:1630f] drawLayer:inContext: bounds={{0, 0}, {300, 300}}

最佳答案

我已经发布了我对类似问题的回答:setNeedsDisplayInMapRect doesn't trigger new drawMapRect: call (只是一个链接,不要在此处重复答案)。

很快:您应该将 setNeedsDisplayInRect 方法的调用分派(dispatch)给 dispatch_get_main_queue()。

关于ios - setNeedsDisplayInRect 在 drawLayer :inContext: 期间调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8157349/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com