zoukankan      html  css  js  c++  java
  • 测试TextKit渲染大文本的效率

    测试TextKit渲染大文本的效率

    TextKit可以用来做精美的电子书,而电子书通常都是txt格式的,那么渲染txt格式的文本的效率如何呢?

    以下来进行测试.

    #import "RootViewController.h"
    #import "FontPool.h"
    #import "YXGCD.h"
    
    @interface RootViewController ()<NSLayoutManagerDelegate>
    
    @end
    
    @implementation RootViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        self.view.backgroundColor = [UIColor blackColor];
        
        [[GCDQueue globalQueue] execute:^{
            NSLog(@"start");
            
            // 数据源
            NSString *string = [NSString stringWithContentsOfURL:[NSBundle.mainBundle URLForResource:@"bubizhidaowoshishui" withExtension:@"txt"] usedEncoding:nil
                                                           error:nil];
            
            // 文本容器
            NSTextStorage *storage = [[NSTextStorage alloc] initWithString:string];
            
            // 段落属性
            NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
            paragraphStyle.lineHeightMultiple  = 1.f;                    // 可变行高,乘因数
            paragraphStyle.lineSpacing         = 5.f;                    // 行间距
            paragraphStyle.minimumLineHeight   = 10.f;                   // 最小行高
            paragraphStyle.maximumLineHeight   = 20.f;                   // 最大行高
            paragraphStyle.paragraphSpacing    = 10.f;                   // 段间距
            paragraphStyle.alignment           = NSTextAlignmentLeft;    // 对齐方式
            paragraphStyle.firstLineHeadIndent = 30.f;                   // 段落首文字离边缘间距
            paragraphStyle.headIndent          = 0.f;                    // 段落除了第一行的其他文字离边缘间距
            paragraphStyle.tailIndent          = 0.f;                    // ???????
            [storage addAttribute:NSParagraphStyleAttributeName
                            value:paragraphStyle
                            range:NSMakeRange(0, storage.string.length)];
            
            // 字体属性
            [storage addAttribute:NSFontAttributeName
                            value:[UIFont fontWithName:CUSTOM_FONT(@"新蒂小丸子体", 0) size:15.f]
                            range:NSMakeRange(0, storage.string.length)];
            
            [storage addAttribute:NSForegroundColorAttributeName
                            value:[UIColor cyanColor]
                            range:NSMakeRange(0, storage.string.length)];
            
            [[GCDQueue mainQueue] execute:^{
                // 文本容器的布局管理器
                NSLayoutManager *layoutManager = [NSLayoutManager new];
                
                NSLog(@"step 1");
                // 开始渲染
                [storage addLayoutManager:layoutManager];
                
                NSLog(@"step 2");
                
                // 分段显示文本容器中的内容
                CGSize size = CGSizeMake(300, 520);
                NSTextContainer *textContainer1 = [[NSTextContainer alloc] initWithSize:size];
                [layoutManager addTextContainer:textContainer1];
                
                
                NSTextContainer *textContainer2 = [[NSTextContainer alloc] initWithSize:size];
                [layoutManager addTextContainer:textContainer2];
                
                
                NSTextContainer *textContainer3 = [[NSTextContainer alloc] initWithSize:size];
                [layoutManager addTextContainer:textContainer3];
                
                NSLog(@"step - 3");
                UITextView *textView = 
                    [[UITextView alloc] initWithFrame:CGRectMake(10, 20,
                                                                 size.width,
                                                                 size.height + 20)
                                        textContainer:textContainer1];
                
                textView.layer.borderWidth = 1;
                textView.scrollEnabled     = NO;
                textView.backgroundColor   = [UIColor clearColor];
                textView.editable          = NO;
                [self.view addSubview:textView];
                
                NSLog(@"step - 4");
            }];
        }];
    }
    
    @end

    测试的文本为310K大小

    以下是测试结果:

    2014-06-06 08:31:00.406 TextKit[4922:1803] start
    2014-06-06 08:31:00.437 TextKit[4922:60b] step 1
    2014-06-06 08:31:01.374 TextKit[4922:60b] step 2
    2014-06-06 08:31:01.376 TextKit[4922:60b] step - 3
    2014-06-06 08:31:02.211 TextKit[4922:60b] step - 4

    从结果中,我们能发现一个规律哦:

    当storage添加layoutManager的时候,此时就已经开始进行一些计算处理了,当我把[storage addLayoutManager:layoutManager];移动到子线程中运行的时候,就会发现后面的UITextView渲染不出文本了,这很容易理解,因为,只有在UI线程(主线程)中执行了渲染操作才会被显示出来,所以,NSTextStorage在添加NSLayoutManager的时候,就已经开始进行布局渲染了.310k的文本花了将近1秒.加上后面的UITextView加载又花了将近1秒,总共花了将近2秒......

    也就是说,渲染300k的文本会在主线程上阻塞2秒的时间,这个延时感用户很难接受吧.....

    有没有什么解决方案呢?

    除了把txt文档分割小一点,别无他法哦,至少我目前没有想到好的方法.

  • 相关阅读:
    不定方程(Exgcd)
    [模板]乘法逆元
    STL-Deque(双端队列)与单调队列的实现
    最优得分 score
    摆书 book
    [模板]树链剖分
    [模板]Splay
    NOIP2013 货车运输
    Java的类类型和类的动态加载
    Java:搜索特定后缀名的文件
  • 原文地址:https://www.cnblogs.com/YouXianMing/p/3771750.html
Copyright © 2011-2022 走看看