I use CATiledLayer in my application, and as a result, this layer is drawn in the background thread. That is, the drawLayer: inContext: method of my delegate is called from the background thread. SetNeedsDisplayInRect, used to cancel invalid parts of CATiledLayer, is always called from the main thread.
Since they are independent streams, sometimes it happens that setNeedsDisplayInRect is called and the background stream is called in the drawLayer: inContext method. I noticed that setNeedsDisplayInRect is ignored in this situation (drawLayer: inContext is not called again).
I registered a bug for Apple because I think this is not true. But itβs hard for me to figure out how to get around this situation. Do you have any good ideas?
EDIT:
I tried out Stanislav's answer using the following code:
- (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);
As indicated, the code does cause the drawing indefinitely, but sometimes between setting NeedsDisplayInRect and a delay of up to 5 seconds and the corresponding drawLayer: inContext: in which nothing else happens. See the Journal below for an example. Pay attention to irregular behavior: in the first second some fragments are redrawn several times, others only once. Then there is a pause of 5 seconds, and the cycle starts again.
This was tested on a simulator with IOS6.0 (I choose this version because earlier versions have another error, which is fixed in version 6.0: sometimes they draw the same fragments).
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}}