2012-09-04 28 views
3

我在drawRect:中給UIVIew畫了一些文字。首先我計算文本高度,然後drawInRect:。代碼波紋管工作:drawInRect error:CGContextSetFont:invalid context 0x0

- (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]]; 
} 

然後我計算文本高度與main_queue dispatch_async和drawInRect,它失敗:

- (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>: CGContextSetFont: invalid context 0x0 
<Error>: CGContextSetTextMatrix: invalid context 0x0 
<Error>: CGContextSetFontSize: invalid context 0x0 
<Error>: CGContextSetTextPosition: invalid context 0x0 
<Error>: CGContextShowGlyphsWithAdvances: invalid context 0x0 

什麼錯誤呢? 如何在另一個線程中計算文本高度以提高速度?

謝謝。

+0

由於dispatch_async塊**不允許對UI進行更改** –

回答

3

您可以從輔助線程使用CoreGraphics和CoreText API。

只有很少的UIKit API可以安全地從輔助線程調用。作爲一般規則,UIKit API僅適用於主線程。

該錯誤表示NULL上下文正在傳遞給CG-API。次要線程默認不會創建一個 - 您必須創建您自己的渲染上下文和目標以在輔助線程上呈現。 UIKit調用只抓取線程上下文堆棧中的頂級上下文 - 上下文堆棧不存在於輔助線程上或上下文中。

就速度而言 - 很難相信一個標籤會導致如此明顯的減速。也許更多的上下文會有幫助

+0

感謝您的回答。在單元格上還有更多其他標籤和子視圖,我只是在這裏爲代碼示例。你是對的,從輔助線程調用'drawInRect:'是不安全的,謝謝你的幫助。 – fannheyward

+0

@fannheyward不用客氣 – justin

1

我有類似的問題,並在圖紙代碼周圍用UIGraphicsPushContext(context)/UIGraphicsPopContext(context)解決。上下文創建與

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

你能詳細解釋一下嗎?我不確定這裏發生了什麼。 – p0lAris

+0

我只創建了一個上下文,並在任何繪圖之前將其推送到圖形上下文堆棧中。 – Vlad