浅析NSTextContainer

TextKit中的NSTextContainer有点晦涩难懂,如果想用TextKit实现文本分页的效果,你是必须要使用NSTextContainer的......

他们的关系是这样子的:

NSTextStorage  ---> NSLayoutManager ---> 多个NSTextContainer

当你添加了几个NSTextContainer的时候,对应的那个NSTextContainer实际上已经分页好了,下面用例子来验证结论:

- (void)viewDidLoad
{
[super viewDidLoad]; // 数据源
NSString *string = [NSString stringWithContentsOfURL:[NSBundle.mainBundle URLForResource:@"bubizhidaowoshishui" withExtension:@"txt"] usedEncoding:nil
error:nil]; // 文本容器
NSTextStorage *storage = [[NSTextStorage alloc] initWithString:string]; // 文本容器的布局管理器
NSLayoutManager *layoutManager = [NSLayoutManager new];
[storage addLayoutManager:layoutManager]; // 分段显示文本容器中的内容
CGSize size = CGSizeMake(, );
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];
NSTextContainer *textContainer4 = [[NSTextContainer alloc] initWithSize:size];
[layoutManager addTextContainer:textContainer4]; // 给TextView添加带有内容和布局的容器
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(, ,
size.width, size.height)
textContainer:textContainer1];
textView.layer.borderWidth = ;
textView.scrollEnabled = NO;
textView.editable = NO;
[self.view addSubview:textView]; // 验证
if (textView.textStorage == storage)
{
NSLog(@"textView.textStorage == storage");
} if (textView.layoutManager == layoutManager)
{
NSLog(@"textView.layoutManager == layoutManager");
} NSLog(@"计算的页码数:%f", [textView sizeThatFits:CGSizeMake(, FLT_MAX)].height / .f);
}

注意看下面的关系:

修改一下源码后,如下打印(注意将容器换成了textContainer2了):

你会发现,textContainer2显示了第二页的内容,但是呢,你会发现整个UITextView的页码变成了119了.

其实,看到这里,结论已经相当明显了.

NSLayoutManager就像一个队列一样,它会将添加到NSLayoutManager中的NSTextContainer自动按照进入队列的顺序来给NSTextContainer赋值,最先进入队列的NSTextContainer将会有着最多显示的内容,往后进入队列的NSTextContainer会依次递减(发现这个花了我半天时间-_-!!).

还有一点内容相当重要哦:)

看起来,你可能觉得UITextView仅仅持有了一个NSTextContainer,其实,他还接管了你在上面定义的那个NSTextStorage以及layoutManager,这一点很容易被忽视掉得.

也就是说(个人观点):

UITextView在获取到了NSTextContainer后,会自动的接管了与这个NSTextContainer相关的所有配置,UITextView将自身包含的textStorage以及layoutManager替换成了NSTextContainer相关配置.

附录:

解析1.3M的txt文本.

花了将近3.3s......

拖动时占用内存的情况:

这内存长的有点恐怖哦:)

浅析NSTextContainer的更多相关文章

  1. SQL Server on Linux 理由浅析

    SQL Server on Linux 理由浅析 今天的爆炸性新闻<SQL Server on Linux>基本上在各大科技媒体上刷屏了 大家看到这个新闻都觉得非常震精,而美股,今天微软开 ...

  2. 【深入浅出jQuery】源码浅析--整体架构

    最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...

  3. 高性能IO模型浅析

    高性能IO模型浅析 服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种: (1)同步阻塞IO(Blocking IO):即传统的IO模型. (2)同步非阻塞IO(Non-blocking  ...

  4. netty5 HTTP协议栈浅析与实践

      一.说在前面的话 前段时间,工作上需要做一个针对视频质量的统计分析系统,各端(PC端.移动端和 WEB端)将视频质量数据放在一个 HTTP 请求中上报到服务器,服务器对数据进行解析.分拣后从不同的 ...

  5. Jvm 内存浅析 及 GC个人学习总结

    从诞生至今,20多年过去,Java至今仍是使用最为广泛的语言.这仰赖于Java提供的各种技术和特性,让开发人员能优雅的编写高效的程序.今天我们就来说说Java的一项基本但非常重要的技术内存管理 了解C ...

  6. 从源码浅析MVC的MvcRouteHandler、MvcHandler和MvcHttpHandler

    熟悉WebForm开发的朋友一定都知道,Page类必须实现一个接口,就是IHttpHandler.HttpHandler是一个HTTP请求的真正处理中心,在HttpHandler容器中,ASP.NET ...

  7. 【深入浅出jQuery】源码浅析2--奇技淫巧

    最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...

  8. 浅析匿名函数、lambda表达式、闭包(closure)区别与作用

    浅析匿名函数.lambda表达式.闭包(closure)区别与作用 所有的主流编程语言都对函数式编程有支持,比如c++11.python和java中有lambda表达式.lua和JavaScript中 ...

  9. word-break|overflow-wrap|word-wrap——CSS英文断句浅析

    ---恢复内容开始--- word-break|overflow-wrap|word-wrap--CSS英文断句浅析 一 问题引入 今天在再次学习 overflow 属性的时候,查看效果时,看到如下结 ...

随机推荐

  1. 数据分析--降维--LDA和PCA

    一.因子分析 因子分析是将具有错综复杂关系的变量(或样本)综合为少数几个因子,以再现原始变量和因子之间的相互关系,探讨多个能够直接测量,并且具有一定相关性的实测指标是如何受少数几个内在的独立因子所支配 ...

  2. 玩转mongodb(四):细说插入、更新、删除和查询

    插入: 使用insert或save方法想目标集合插入一个文档: db.person.insert({"name":"ryan","age": ...

  3. The version of SOS does not match the version of CLR you are debugging; SOS.dll版本不匹配; Dump文件不同环境mscordacwks.dll版本问题

    The version of SOS does not match the version of CLR you are debugging 和 PDB symbol for clr.dll not ...

  4. 一个在linux环境执行io操作的bug

    今天项目有了一个奇葩的要求...是什么呢 后台上传了视频后,解析其中的时长,和预览图,并拼接在一起,然而,之东西并不是太麻烦,很快写好了,在本地测试后也没有问题,嗯,发布到测试环境后,一个jar包报错 ...

  5. Electron与WEB桌面应用程序开发及其它

    这几天在构思项目,研究了一下Electron,记录下来. 说起WEB桌面程序,当前最火的就是Electron了. Electron的架构用一句话总结,就是一个main.js进程加上一个或数个chrom ...

  6. JAVA-7NIO之Socket/ServerSocket Channel

    一.ServerSocketChannel Java NIO中的 ServerSocketChannel 是一个可以监听新进来的TCP连接的通道, 就像标准IO中的ServerSocket一样.Ser ...

  7. Linux下的MongoDB安装&启动&关闭

    一.下载安装包 下载地址 二.解压安装包 $ tar -zxvf mongodb-linux-x86_64-3.0.6.tgz 三.复制到指定的目录下 $ mv mongodb-linux-x86_6 ...

  8. readtimeout

    请求头去掉content-length,未找到明确原因.

  9. sql中把时间转换成xx年xx月xx日

    DECLARE @dt datetime SET @dt=GETDATE()--1.短日期格式:yyyy-m-d SELECT STUFF(STUFF(CONVERT(char(8),@dt,112) ...

  10. C#,一些非常简单但应该知道的知识点

    1.本地变量 一看这个标题你可能会一愣,这是个什么东东.看个小例子: static void main(){   int a=10;   MyClass mc=new MyClass();} 呵呵,这 ...