Consider this simple UIView subclass in an ARC-enabled iOS app that draws on the view when the screen is touched:
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint location = [[touches anyObject] locationInView:self];
int padding = brushSize / 2;
CGRect brushRect = CGRectMake(
location.x - padding, location.y - padding,
brushSize, brushSize
);
[self setNeedsDisplayInRect:brushRect];
}
- (void)drawRect:(CGRect)rect {
NSDate *start = [NSDate date];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextDrawImage(context, rect, brushImage);
NSLog(@"%f", [start timeIntervalSinceNow]);
}
In this example, brushImage
is a square bitmap, and brushSize
is an int describing the width and height of the bitmap.
I consistently get log output like this:
-0.131658
-0.133998
-0.143314
-0.007132
-0.006968
-0.007444
-0.006733
-0.008574
-0.007163
-0.006560
-0.006958
The first calls to drawRect take much longer to complete than subsequent calls, and drawRect continues to be consistently fast thereafter. It's only on the first calls after the view is initialized that drawRect is slow.
I see similar results in both the simulator and all physical devices I've tried. The initial calls always take much longer to complete.
Why is drawRect / CGContextDrawImage so slow on the initial calls? And more importantly, how can I fix this?