如何在iOS5中绘制NSAttribute字符串?

如何在iOS5中绘制NSAttribute字符串?,ios5,crash,nsattributedstring,Ios5,Crash,Nsattributedstring,当我试图绘制一个NSAttribute字符串并在iOS5模拟器中运行它时,我遇到了一个崩溃。在iOS6中,它运行良好。我不明白我做错了什么,因为从我阅读的内容来看,我的代码应该也适用于iOS5。我的设置: 代码4.6.2 iOS 6.1 SDK iOS 5.1部署目标 我运行以下代码: - (void)drawRect:(CGRect)rect { NSDictionary *txtAttr = @{ (NSString *)kCTFontAttributeName

当我试图绘制一个NSAttribute字符串并在iOS5模拟器中运行它时,我遇到了一个崩溃。在iOS6中,它运行良好。我不明白我做错了什么,因为从我阅读的内容来看,我的代码应该也适用于iOS5。我的设置:

  • 代码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
0x140c5a:calll 0x11c812;TCFRetained::Retain(uu CFDictionary const*)
0x140c5f:movl 8(%ebp),%eax
0x140c62:movl 4(%eax),%eax
0x140c65:movl 20(%eax),%eax
0x140c68:movl 8(%eax),%eax;我在这里得到一个线程1:EXC\u BAD\u访问(代码=2,地址=0x08)
0x140c6b:testl%eax,%eax
0x140c6d:je 0x140d0c;TatAttributes::TatAttributes(uu CFDictionary const*)+482

错误在于使用
UIFont
。IOS5预计一个核心基础类型是<代码> CTBONT/<代码>。下面是我用来让它工作的代码:

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

使用字体手册应用程序查找字体并使用PostScript名称。如果我没有读到:

错误是使用
UIFont
,我就不会明白这一点。IOS5预计一个核心基础类型是<代码> CTBONT/<代码>。下面是我用来让它工作的代码:

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

使用字体手册应用程序查找字体并使用PostScript名称。如果我没有阅读:

我不知道是否要逐行绘制文本,但以下是我用于在自定义UIView上绘制NSAttribute字符串的代码: 我根据您的属性字符串更改了代码:

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

我希望我没有忘记任何东西,因为我还对属性文本执行了一些计算,为了更好的示例,我删除了它们


希望这有帮助;)

我不知道您是否希望逐行绘制文本,但以下是我的代码,用于在自定义UIView上绘制NSAttribute字符串: 我根据您的属性字符串更改了代码:

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

我希望我没有忘记任何东西,因为我还对属性文本执行了一些计算,为了更好的示例,我删除了它们


希望这有帮助;)

我仍然不确定这是否会导致正确处理内存。我找不到任何关于如何处理非免费网桥的CF类型的文档。我仍然不确定这是否会导致正确处理内存。我找不到任何关于如何处理非免费网桥的CF类型的文档。