浅析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. 【好书分享】容器网络到kubernetes网络

    Nginx 公司的 Michael Hausenblas 发布了一本关于 docker 和 kubernetes 中的容器网络的小册子.这份资料一共 72 页,是大家由浅入深的了解 Docker 和 ...

  2. nlp 总结 分词,词义消歧,词性标注,命名体识别,依存句法分析,语义角色标注

    分词 中文分词 (Word Segmentation, WS) 指的是将汉字序列切分成词序列. 因为在汉语中,词是承载语义的最基本的单元.分词是信息检索.文本分类.情感分析等多项中文自然语言处理任务的 ...

  3. java的NIO和AIO

    1. 什么是NIO NIO是New I/O的简称,与旧式的基于流的I/O方法相对,从名字看,它表示新的一套Java I/O标 准.它是在Java 1.4中被纳入到JDK中的,并具有以下特性: NIO是 ...

  4. Nodejs学习笔记(八)—Node.js + Express 实现上传文件功能(felixge/node-formidable)

    前言 前面讲了一个构建网站的示例,这次在此基础上再说说web的常规功能----文件上传,示例以一个上传图片的功能为例子 上传功能命名用formidable实现,示例很简单! PS:最近比较忙,距上一次 ...

  5. java面试⑥框架部分

    2.5.1 什么是框架: 2.5.2 MVC模式 2.5.3 MVC框架 2.5.4 简单讲一下struts2的执行流程 2.5.5 Struts2中的拦截器,你都用它干什么? 2.5.6 简单讲一下 ...

  6. Week4——结对练习&团队作业1

    Deadline: 2017-10-14 10:00PM,以博客发表日期为准. 评分基准: 按时交 - 有分(结对代码-10分,结对博客-10分,团队博客-10分),检查的项目包括后文的三个方面 按要 ...

  7. [POI 2014]RAJ-Rally

    Description 题库链接 给定一个 \(N\) 个点 \(M\) 条边的有向无环图,每条边长度都是 \(1\).请找到一个点,使得删掉这个点后剩余的图中的最长路径最短. \(1\leq N\l ...

  8. 17.async 函数

    async 函数 async 函数 含义 ES2017 标准引入了 async 函数,使得异步操作变得更加方便. async 函数是什么?一句话,它就是 Generator 函数的语法糖. 前文有一个 ...

  9. Windows2012开机启动项设置

    最简单方式 开始->运行->输入shell:startup 在打开的启动文件夹中,将需要启动程序的快捷方式复制进去,完工 重启试试吧 https://blog.csdn.net/tmton ...

  10. MVC 之HTML辅助方法

    顾名思义,HTML辅助方法(HTML Helper)就是用来辅助产生HTML之用,在开发View的时候一定会面对许多HTML标签,处理这些HTML的工作非常繁琐,为了降低View的复杂度,可以使用HT ...