2013-05-02 54 views
0

當我嘗試繪製一個NSAttributedString並在iOS5模擬器中運行它時,我得到一個崩潰。在iOS6中它運行良好。我不明白我做錯了什麼,因爲從我讀的代碼中我應該也可以在iOS5上工作。我的設置:如何在iOS5中繪製NSAttributedString?

  • 的Xcode 4.6.2
  • 的iOS 6.1 SDK
  • 的iOS 5.1部署目標

我運行下面的代碼:

- (void)drawRect:(CGRect)rect 
{ 

    NSDictionary *txtAttr = @{ 
     (NSString *)kCTFontAttributeName : [UIFont boldSystemFontOfSize:16] 
    }; 


    NSMutableAttributedString * string = [[NSMutableAttributedString alloc] initWithString:@"foobar" attributes:txtAttr]; 


    CGContextRef ctx = UIGraphicsGetCurrentContext(); 
    // flip context 
    CGContextSaveGState(ctx); 
    CGContextTranslateCTM(ctx, 0, self.bounds.size.height); 
    CGContextScaleCTM(ctx, 1, -1); 
// I get a crash on the line below 
    CTLineRef line = CTLineCreateWithAttributedString(
     (__bridge CFAttributedStringRef)string 
    ); 
    CGContextSetTextPosition(ctx, 0, 4); 
    CTLineDraw(line, ctx); 
    CFRelease(line); 

    CGContextRestoreGState(ctx); 
} 

這崩潰的CTLineCreateWithAttributedString與堆棧跟蹤:

#0 0x00140c68 in TAttributes::TAttributes(__CFDictionary const*)() 
#1 0x0011c499 in TTypesetterAttrString::Initialize(__CFAttributedString const*)() 
#2 0x0011c313 in TTypesetterAttrString::TTypesetterAttrString(__CFAttributedString const*)() 
#3 0x0010db14 in CTLineCreateWithAttributedString() 
#4 0x00065e5f in -[AttributedLabel drawRect:] at AttributedLabel.m:77 
#5 0x003c8bd3 in -[UIView(CALayerDelegate) drawLayer:inContext:]() 
#6 0x002a7963 in -[CALayer drawInContext:]() 
#7 0x002b9f80 in backing_callback(CGContext*, void*)() 
#8 0x001d83fd in CABackingStoreUpdate_() 
#9 0x002b9e2e in CA::Layer::display_()() 
#10 0x002a7a3d in -[CALayer _display]() 
#11 0x002adfd5 in CA::Layer::display()() 
#12 0x002a7a63 in -[CALayer display]() 
#13 0x002b19ae in CA::Layer::display_if_needed(CA::Transaction*)() 
#14 0x00236509 in CA::Context::commit_transaction(CA::Transaction*)() 
#15 0x002383f6 in CA::Transaction::commit()() 
#16 0x00237ad0 in CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*)() 
#17 0x0140c99e in __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__() 
#18 0x013a3640 in __CFRunLoopDoObservers() 
#19 0x0136f4c6 in __CFRunLoopRun() 
#20 0x0136ed84 in CFRunLoopRunSpecific() 
#21 0x0136ec9b in CFRunLoopRunInMode() 
#22 0x018157d8 in GSEventRunModal() 
#23 0x0181588a in GSEventRun() 
#24 0x0038a626 in UIApplicationMain() 

在崩潰發生的位置如下圖所示:

0x140c5a: calll 0x11c812     ; TCFRetained<__CFDictionary const*>::Retain(__CFDictionary const*) 
0x140c5f: movl 8(%ebp), %eax 
0x140c62: movl 4(%eax), %eax 
0x140c65: movl 20(%eax), %eax 
0x140c68: movl 8(%eax), %eax ;I get a Thread 1: EXC_BAD_ACCESS (code=2, address=0x08) here 
0x140c6b: testl %eax, %eax 
0x140c6d: je  0x140d0c     ; TAttributes::TAttributes(__CFDictionary const*) + 482 

回答

2

的錯誤是使用UIFont。 iOS5需要一個CTFont,這是一個核心基礎類型。以下是我用來使其工作的代碼:

CTFontRef font = CTFontCreateWithName((CFStringRef)@"HelveticaNeue-Bold", 16, NULL); 
NSDictionary *txtAttr = @{ 
    (NSString *)kCTFontAttributeName : (id)CFBridgingRelease(font) 
}; 

使用您的字體書應用程序來定位字體並使用PostScript名稱。我不會想通了這一點,如果我還沒有看過:NSAttributedString in CATextLayer causes EXC_BAD_ACCESS (ios 5.0)

+0

我仍然不確定如果這會導致內存正確處理。我找不到關於如何處理非免費橋接器的CF類型的任何文檔。 – 2013-05-02 11:36:38

2

我不知道,如果你想畫一行文本行,但這裏是我的代碼,我用來繪製NSAttributedString一個自定義的UIView: 我根據你的屬性串改變了代碼:

- (void)drawRect:(CGRect)rect { 
    NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:@"yourString"]; 
    UIFont *font = [UIFont boldSystemFontOfSize:16]; 
    CTFontRef fontR = CTFontCreateWithName((CFStringRef)font.fontName, font.pointSize, NULL); 
    [attrString addAttribute:(NSString*)kCTFontAttributeName 
           value:(id)fontR 
           range:NSMakeRange(0, [yourText length])]; 
    CFRelease(fontR); 
    CGMutablePathRef path = CGPathCreateMutable(); 
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attrString); 
     // added 3 pixels at the top of the frame so that the text is not cuted 
    CGRect newRect = CGRectMake(rect.origin.x, rect.origin.y - 3, rect.size.width, rect.size.height); 
    CGPathAddRect(path, NULL, newRect); 
    CTFrameRef frameRef = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL); 
    CFRelease(framesetter); 
    CGPathRelease(path); 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextSetTextMatrix(context, CGAffineTransformIdentity); 
    CGContextTranslateCTM(context, 0, self.bounds.size.height); 
    CGContextScaleCTM(context, 1.0, -1.0); 
    CTFrameDraw(frameRef, context); 
    CFRelease(frameRef); 
    [super drawRect:newRect]; 

}

我希望我沒有忘記什麼,因爲我也執行的屬性文本一些計算,我刪除了他們一個更好的例子。

希望這有助於;)