Iphone 核心图形文本比核心文本快得多-我觉得我遗漏了一些东西

Iphone 核心图形文本比核心文本快得多-我觉得我遗漏了一些东西,iphone,objective-c,ios,core-graphics,core-text,Iphone,Objective C,Ios,Core Graphics,Core Text,下面是我用来在核心图形中显示一些文本的代码: int y = MESSAGE_FRAME.origin.y + 8; if (month) y = y + 27; int height = [JHomeViewCellContentView heightOfMessage:self.entry.message]; CGRect rect = CGRectMake(MESSAGE_FRAME.origin.x + 8, y, MESSAGE_FRAME.size.width - 16, hei

下面是我用来在核心图形中显示一些文本的代码:

int y = MESSAGE_FRAME.origin.y + 8;

if (month) y = y + 27;
int height = [JHomeViewCellContentView heightOfMessage:self.entry.message];

CGRect rect = CGRectMake(MESSAGE_FRAME.origin.x + 8, y, MESSAGE_FRAME.size.width - 16, height);

UIFont *font = [UIFont fontWithName:@"Crimson" size:15.0f];

[[UIColor colorWithWhite:0.2 alpha:1.0] setFill];

[self.entry.message drawInRect:rect withFont:font lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentLeft];
如果我想在核心文本中显示相同的文本,下面是代码:

CGRect rect2 = CGRectMake(MESSAGE_FRAME.origin.x + 8, self.bounds.size.height - y - height + 2, MESSAGE_FRAME.size.width - 16, height);


    UIFont *font = [UIFont fontWithName:@"Crimson" size:15.0f];
    CGFloat lineHeight = [font lineHeight];

    CTFontRef fontRef = CTFontCreateWithName((CFStringRef)@"Crimson", 15.0f, NULL);

    CGFloat lineSpacing = 0;

    CTParagraphStyleSetting settings[] = {
        { kCTParagraphStyleSpecifierMinimumLineHeight, sizeof(lineHeight), &lineHeight },
        { kCTParagraphStyleSpecifierMaximumLineSpacing, sizeof(lineSpacing), &lineSpacing },

    };

    CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(settings, sizeof(settings) / sizeof(settings[0]));

    NSMutableDictionary *attDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                   (__bridge_transfer id)fontRef, (NSString *)kCTFontAttributeName,
                                          (id)[[UIColor colorWithWhite:0.2 alpha:1.0] CGColor], (NSString *)kCTForegroundColorAttributeName,
                                          paragraphStyle, kCTParagraphStyleAttributeName,
                                          nil];

     NSAttributedString *attString = [[NSAttributedString alloc] initWithString:self.entry.message attributes:attDictionary];

    //Flip the coordinate system
    CGContextSetTextMatrix(context, CGAffineTransformIdentity);
    CGContextTranslateCTM(context, 0, self.bounds.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);



    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddRect(path, NULL, rect2);


    self.framesetter = CTFramesetterCreateWithAttributedString((__bridge_retained CFAttributedStringRef)attString);
    CTFrameRef theFrame = CTFramesetterCreateFrame(self.framesetter, CFRangeMake(0, [attString length]), path, NULL);

    CFRelease(path);

    CTFrameDraw(theFrame, context);
    CFRelease(theFrame);
显然,尽管核心文本更冗长,但它的速度要比核心图形快,这也是我学会如何做的原因。但在仪器中运行这段代码时,核心图形达到5ms,而核心文本达到14ms。我觉得我错过了一些东西。drawInRect的速度快了近3倍,我听说它应该慢一点。我已经尽我所知完善了底部的代码,但我不是专家,我希望能得到任何帮助


为了澄清,我在视图上绘制了一块文本。这就是我想要做的。所有的文本都有相同的外观。

我不使用CT的东西,但在我看来,你在每个绘图上都设置了不变字体和其他属性。尝试将所有内容分解为注释“翻转坐标系并缓存ATTSING字符串”


这将提高速度,以便进行更好的头对头测试。

NSMutableAttributedString确实允许您通过 替换字符范围:带字符串:

设置属性字典后,可以通过以下方式限制对属性字符串的进一步字符串更新: [myAttString ReplaceCharactersRange:NSMakeRange(0,myAttString.text.length)和字符串:新闻字符串]

还有,我发现CGContextSetTextMatrix在使用CTFrameDraw时几乎没有任何意义

另一个提示是,我在CTFontRef和CTParagraphStyleRef上没有看到任何版本。它们也遵循“创建规则”,需要是CFRelease()


我一直在努力完成自己的核心文本学习曲线最近,似乎取得了一些有希望的结果。我希望您自己的优化也能给您带来类似的希望。

问题是,虽然属性保持不变,但字符串本身每次都会更改。当您无法设置NSMutableAttributedString的字符串时,我该如何缓存它?我明白了。嗯。这些属性都不涉及字符字符级别,因此一个想法是替换可变属性字符串中的所有字节,但这听起来很粗略。至少,您可以缓存ATTDicondary(无论如何,大部分工作都在那里)然后每次分配一个新的不可变的属性字符串。核心文本的优势在于文本布局,而底层的绘图代码是在核心图形中实现的,我不认为在简单的文本绘图中它可以更快。