浅析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 属性的时候,查看效果时,看到如下结 ...
随机推荐
- php发送get请求
感谢:http://www.zoneself.org/2014/07/21/content_2665.html 1.用PHP发送get请求,很简单: <?php $url='http://www ...
- Cache写机制:Write-through与Write-back
cache through https://www.cnblogs.com/gordonkong/p/7161809.html 原文地址:https://blog.csdn.net/wyzxg/art ...
- SQLite菜鸟教程
学习链接:http://www.runoob.com/sqlite/sqlite-trigger.html
- if 和case
select case 'O' when 'O' then (1*5-6) when 'C' then (1*5-6) when 'EC' then (1*5-6) --else null --end ...
- Echart 改变X轴、Y轴、折线的颜色和数值
在操作E-chart时需要根据需求改变颜色和属性 图1: option = { xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed', 'Thu' ...
- spark算子集锦
Spark 是大数据领域的一大利器,花时间总结了一下 Spark 常用算子,正所谓温故而知新. Spark 算子按照功能分,可以分成两大类:transform 和 action.Transform 不 ...
- Spring Boot 表单验证、AOP统一处理请求日志、单元测试
一.使用@Valid表单验证 于实体类中添加@Min等注解 @Entity public class Girl { @Id @GeneratedValue private Integer id; pr ...
- CodeForces762A
A. k-th divisor time limit per test:2 seconds memory limit per test:256 megabytes input:standard inp ...
- 总结oninput、onchange与onpropertychange事件的使用方法和差别
onchange事件仅仅在键盘或者鼠标操作改变对象属性,且失去焦点时触发,脚本触发无效:而onkeydown/onkeypress/onkeyup在处理复制.粘贴.拖拽.长按键(按住键盘不放)等细节上 ...
- linq中如何实现多个条件的联合查询
目前接触处理数据这一块比较多,在处理内存中的数据源的时候我一般使用的是linq,linq使用起来像sql语句一样,用法简单,功能强大. 最近需要实现一个从两个不同的文件读取不同的数据,然后根据这两个数 ...