浅析NSTextContainer
浅析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的更多相关文章
- SQL Server on Linux 理由浅析
SQL Server on Linux 理由浅析 今天的爆炸性新闻<SQL Server on Linux>基本上在各大科技媒体上刷屏了 大家看到这个新闻都觉得非常震精,而美股,今天微软开 ...
- 【深入浅出jQuery】源码浅析--整体架构
最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...
- 高性能IO模型浅析
高性能IO模型浅析 服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种: (1)同步阻塞IO(Blocking IO):即传统的IO模型. (2)同步非阻塞IO(Non-blocking ...
- netty5 HTTP协议栈浅析与实践
一.说在前面的话 前段时间,工作上需要做一个针对视频质量的统计分析系统,各端(PC端.移动端和 WEB端)将视频质量数据放在一个 HTTP 请求中上报到服务器,服务器对数据进行解析.分拣后从不同的 ...
- Jvm 内存浅析 及 GC个人学习总结
从诞生至今,20多年过去,Java至今仍是使用最为广泛的语言.这仰赖于Java提供的各种技术和特性,让开发人员能优雅的编写高效的程序.今天我们就来说说Java的一项基本但非常重要的技术内存管理 了解C ...
- 从源码浅析MVC的MvcRouteHandler、MvcHandler和MvcHttpHandler
熟悉WebForm开发的朋友一定都知道,Page类必须实现一个接口,就是IHttpHandler.HttpHandler是一个HTTP请求的真正处理中心,在HttpHandler容器中,ASP.NET ...
- 【深入浅出jQuery】源码浅析2--奇技淫巧
最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...
- 浅析匿名函数、lambda表达式、闭包(closure)区别与作用
浅析匿名函数.lambda表达式.闭包(closure)区别与作用 所有的主流编程语言都对函数式编程有支持,比如c++11.python和java中有lambda表达式.lua和JavaScript中 ...
- word-break|overflow-wrap|word-wrap——CSS英文断句浅析
---恢复内容开始--- word-break|overflow-wrap|word-wrap--CSS英文断句浅析 一 问题引入 今天在再次学习 overflow 属性的时候,查看效果时,看到如下结 ...
随机推荐
- 【好书分享】容器网络到kubernetes网络
Nginx 公司的 Michael Hausenblas 发布了一本关于 docker 和 kubernetes 中的容器网络的小册子.这份资料一共 72 页,是大家由浅入深的了解 Docker 和 ...
- nlp 总结 分词,词义消歧,词性标注,命名体识别,依存句法分析,语义角色标注
分词 中文分词 (Word Segmentation, WS) 指的是将汉字序列切分成词序列. 因为在汉语中,词是承载语义的最基本的单元.分词是信息检索.文本分类.情感分析等多项中文自然语言处理任务的 ...
- java的NIO和AIO
1. 什么是NIO NIO是New I/O的简称,与旧式的基于流的I/O方法相对,从名字看,它表示新的一套Java I/O标 准.它是在Java 1.4中被纳入到JDK中的,并具有以下特性: NIO是 ...
- Nodejs学习笔记(八)—Node.js + Express 实现上传文件功能(felixge/node-formidable)
前言 前面讲了一个构建网站的示例,这次在此基础上再说说web的常规功能----文件上传,示例以一个上传图片的功能为例子 上传功能命名用formidable实现,示例很简单! PS:最近比较忙,距上一次 ...
- java面试⑥框架部分
2.5.1 什么是框架: 2.5.2 MVC模式 2.5.3 MVC框架 2.5.4 简单讲一下struts2的执行流程 2.5.5 Struts2中的拦截器,你都用它干什么? 2.5.6 简单讲一下 ...
- Week4——结对练习&团队作业1
Deadline: 2017-10-14 10:00PM,以博客发表日期为准. 评分基准: 按时交 - 有分(结对代码-10分,结对博客-10分,团队博客-10分),检查的项目包括后文的三个方面 按要 ...
- [POI 2014]RAJ-Rally
Description 题库链接 给定一个 \(N\) 个点 \(M\) 条边的有向无环图,每条边长度都是 \(1\).请找到一个点,使得删掉这个点后剩余的图中的最长路径最短. \(1\leq N\l ...
- 17.async 函数
async 函数 async 函数 含义 ES2017 标准引入了 async 函数,使得异步操作变得更加方便. async 函数是什么?一句话,它就是 Generator 函数的语法糖. 前文有一个 ...
- Windows2012开机启动项设置
最简单方式 开始->运行->输入shell:startup 在打开的启动文件夹中,将需要启动程序的快捷方式复制进去,完工 重启试试吧 https://blog.csdn.net/tmton ...
- MVC 之HTML辅助方法
顾名思义,HTML辅助方法(HTML Helper)就是用来辅助产生HTML之用,在开发View的时候一定会面对许多HTML标签,处理这些HTML的工作非常繁琐,为了降低View的复杂度,可以使用HT ...