fannheyward
fannheyward

Reputation: 19277

drawInRect error: CGContextSetFont: invalid context 0x0

I draw some text to UIVIew in drawRect:. First I calculate text height and then drawInRect:. The code bellow works:

- (void)drawRect:(CGRect)rect
{
    CGFloat titleHeight = [self heightForText:_entry.title
                                     withFont:[UIFont systemFontOfSize:12.0f]];

    CGRect r = CGRectMake(54, 6, kCellTextWidth, titleHeight);
    [_entry.title drawInRect:r withFont:[UIFont titleFont]];
}

Then I calculate text height with dispatch_async and drawInRect in main_queue, it fails:

- (void)drawRect:(CGRect)rect
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        CGFloat titleHeight = [self heightForText:_entry.title
                                         withFont:[UIFont systemFontOfSize:12.0f]];

        dispatch_async(dispatch_get_main_queue(), ^{
            CGRect r = CGRectMake(54, 6, kCellTextWidth, titleHeight);
            [_entry.title drawInRect:r withFont:[UIFont titleFont]];
        });
    });
}

error:

 <Error>: CGContextSetFont: invalid context 0x0
 <Error>: CGContextSetTextMatrix: invalid context 0x0
 <Error>: CGContextSetFontSize: invalid context 0x0
 <Error>: CGContextSetTextPosition: invalid context 0x0
 <Error>: CGContextShowGlyphsWithAdvances: invalid context 0x0

What's the error mean? How can I calculate text height in another thread in order to improve speed?

Thank you.

Upvotes: 3

Views: 2342

Answers (2)

Vlad
Vlad

Reputation: 221

I had similar issue and solved it with UIGraphicsPushContext(context)/UIGraphicsPopContext(context) around the drawing code. context was created with

CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(NULL, width, height, 8, 0, space, kCGImageAlphaPremultipliedLast);

Upvotes: 1

justin
justin

Reputation: 104698

You can use CoreGraphics and CoreText APIs from secondary threads.

There are only very few UIKit APIs which are safe to call from secondary threads. As a general rule, UIKit APIs are intended for the main thread only.

The error means that NULL contexts are being passed to CG-APIs. The secondary threads do not create one by default -- you must create your own rendering context and destination to render on a secondary thread. UIKit calls just grab the top context on the thread's context stack -- the context stack does not exist on the secondary thread, or in this context.

As far as speed -- it's hard to believe one label would cause such a noticeable slow down. Perhaps more context would help.

Upvotes: 3

Related Questions