http://www.bubuko.com/infodetail-382485.html

标签:des   class   style   代码   html   使用   问题   文件   数据

这篇文章是我的【iOS开发每日小笔记】系列中的一片,记录的是今天在开发工作中遇到的,可以用很短的文章或很小的demo演示解释出来的小心得小技巧。它们可能会给用户体验、代码效率得到一些提升,或是之前自己没有接触过的技术,很开心的学到了,放在这里得瑟一下。90%的作用是帮助自己回顾、记忆、复习。

测试组的小伙伴们大显神威,iOS8刚发布,他们就把测试设备急速升级了,然后就是扑面而来的各种bug和他们各种幸灾乐祸的笑。没办法,老老实实修复bug!

来看看今天我遇到的一个问题:

项目中,我将一个简化的HTML格式的字符串读进内存,然后以NSHTMLTextDocumentType类型为option,初始化了一个NSAttributedString类型的实例,并将它用UITextView显示出来。

原本在iOS7中,显示没有任何问题,不论是设置颜色的地方,还是下划线,都完全OK。但是升级了iOS8以后,UITextView完全不显示了。log里的报错也是让人摸不着头脑:

2014-09-25 21:48:36.495 AttributedTextIOS8Demo[3163:24438] -[__NSCFString _getValue:forType:]: unrecognized selector sent to instance 0xae846f0
2014-09-25 21:48:36.795 AttributedTextIOS8Demo[3163:24438] <NSATSTypesetter: 0xaebd580>: Exception -[__NSCFString _getValue:forType:]: unrecognized selector sent to instance 0xae846f0 raised during typesetting layout manager <NSLayoutManager: 0xaebc9f0>
1 containers, text backing has 69 characters
Currently holding 69 glyphs.
Glyph tree contents: 69 characters, 69 glyphs, 1 nodes, 32 node bytes, 512 storage bytes, 544 total bytes, 7.88 bytes per character, 7.88 bytes per glyph
Layout tree contents: 69 characters, 69 glyphs, 0 laid glyphs, 0 laid line fragments, 1 nodes, 32 node bytes, 0 storage bytes, 32 total bytes, 0.46 bytes per character, 0.46 bytes per glyph, 0.00 laid glyphs per laid line fragment, 0.00 bytes per laid line fragment
, glyph range {0 69}. Ignoring...
2014-09-25 21:48:36.836 AttributedTextIOS8Demo[3163:24438] -[__NSCFString _getValue:forType:]: unrecognized selector sent to instance 0xae846f0
2014-09-25 21:48:36.837 AttributedTextIOS8Demo[3163:24438] <NSATSTypesetter: 0xaebd580>: Exception -[__NSCFString _getValue:forType:]: unrecognized selector sent to instance 0xae846f0 raised during typesetting layout manager <NSLayoutManager: 0xaebc9f0>
1 containers, text backing has 69 characters
Currently holding 69 glyphs.
Glyph tree contents: 69 characters, 69 glyphs, 1 nodes, 32 node bytes, 512 storage bytes, 544 total bytes, 7.88 bytes per character, 7.88 bytes per glyph
Layout tree contents: 69 characters, 69 glyphs, 0 laid glyphs, 0 laid line fragments, 1 nodes, 32 node bytes, 0 storage bytes, 32 total bytes, 0.46 bytes per character, 0.46 bytes per glyph, 0.00 laid glyphs per laid line fragment, 0.00 bytes per laid line fragment
, glyph range {0 69}. Ignoring...

我看了看,觉得大概意思就是对一个__NSCFString对象调用了一个不属于它的方法_getValue:forType:,而且,竟然没有crash!但是这也太抽象了,完全不知道问题出在哪儿。我只好使用杀手锏,逐个语句块分析,经过半个小时的各种google搜索(还得各种FQ= =)和代码分析,终于发现原来问题出在设置“下划线”这个环节上。

先来看一下我的问题代码:

 1 - (void)viewDidLoad {
2 [super viewDidLoad];
3 // Do any additional setup after loading the view, typically from a nib.
4
5 NSString *data = [[NSBundle mainBundle] pathForResource:@"111" ofType:@"plist"];// 读取文件
6 NSMutableDictionary *infoDict = [NSMutableDictionary dictionaryWithContentsOfFile:data];// 读取文件中的数据
7 NSString *string = [infoDict objectForKey:@"aa"];// 取出String数据
8
9 NSTextStorage *storage = [[NSTextStorage alloc] initWithData:[string dataUsingEncoding:NSUTF8StringEncoding] options:@{NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType} documentAttributes:nil error:nil];
// 以HTML的方式初始化NSTextStorage
10 [storage addAttribute:NSUnderlineStyleAttributeName value:[NSString stringWithFormat:@"%d", NSUnderlineStyleSingle] range:NSMakeRange(10, 20)];// 设置下划线
11
12 NSDictionary *dict=[NSDictionary dictionaryWithObjectsAndKeys:storage,@"storage", nil];
13
14 UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 40, 320, 300)];
15 textView.attributedText = [dict objectForKey:@"storage"];
16
17 [self.view addSubview:textView];
18 }

我的Value设置的是[NSString stringWithFormat:@"%d", NSUnderlineStyleSingle],由于iOS7中这样完全没有问题,所以我一直认为这样是对的!但是事实上,iOS8中,这样竟是错的!参考:

https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/AttributedStrings/Articles/standardAttributes.html

原来,NSUnderlineStyleAttributeName应该是NSNumber类型,改为[NSNumbernumberWithInt:NSUnderlineStyleSingle]就正确无误了。

难怪出现“_getValue:forType:”这样的错误,还真的是因为内部在调用该方法的时候,发现接受消息的对象是个String类型,而不是Number。这样就说得通了!

NSUnderlineStyleAttributeName

The value of this attribute is an NSNumber object containing an integer. This value indicates whether the text is underlined and corresponds to one of the constants described in “Underline and Strikethrough Style Attributes”. The default value for this attribute is NSUnderlineStyleNone.

为什么iOS7中可以用NSString,iOS8中就会报错必须使用NSNumber呢?或许是iOS8为了适配Swift强类型,才做了这样的改变?

demo地址:https://github.com/pigpigdaddy/AttributedTextIOS8Demo

转:【iOS开发每日小笔记(十一)】iOS8更新留下的“坑” NSAttributedString设置下划线 NSUnderlineStyleAttributeName 属性必须为NSNumber的更多相关文章

  1. 《iOS开发指南》要改iOS8版本了,听听您的意见?

    <iOS开发指南>要改iOS8版本了,听听您的意见?参加问卷同学均可获得智捷课堂50元代金卡一张,同时抽取一名同学赠送即将出版的基于iOS8的<iOS开发指南>一本,欢迎大家填 ...

  2. iOS 开发之照片框架详解之二 —— PhotoKit 详解(下)

    本文链接:http://kayosite.com/ios-development-and-detail-of-photo-framework-part-three.html 这里接着前文<iOS ...

  3. iOS开发的小技巧(断点打印)

    iOS开发中我们会碰到这样的需求:打印沙盒目录,打印对象信息,对象信息可以通过断点查看,有时候对象属性繁多时看起来又比较麻烦. 今天学到一个比较实用的方法: 在运行时打一个断点,当程序停在这个断点后, ...

  4. iOS开发调试技巧总结(持续更新中)

    作者:乞力马扎罗的雪  原文 对于软件开发而言,调试是必须学会的技能,重要性不言而喻.对于调试的技能,基本上是可以迁移的,也就是说你以前在其他平台上掌握的很多调试技巧,很多也是可以用在iOS开发中.不 ...

  5. IOS开发之小实例--创建一个简单的用于视频录制和回放的应用程序

    前言:还是看了一下国外的入门IOS文章:<Create a Simple App for Video Recording and Playback>,主要涉及视频录制和回放的功能的基本实现 ...

  6. iOS开发ReactiveCocoa学习笔记(一)

    学习 RAC 我们首先要了解 RAC 都有哪些类 RACSignal RACSubject RACSequence RACMulticastConnection RACCommand 在学习的时候写了 ...

  7. iOS开发的小技巧

    转自简书:http://www.jianshu.com/p/50b63a221f09  http://www.jianshu.com/p/08f194e9904c 原作者:叶孤城___ self.ta ...

  8. iOS开发常用小技巧记录(持续更新)

    以下问题都是自己在项目中遇到的,解决问题的方法肯定有多种,我所列举的不一定就是最好的解决办法.如有问题欢迎大家指正,补充,交流. 解决同时按两个按钮进两个view的问题.[button setExcl ...

  9. IOS开发之小实例--使用UIImagePickerController创建一个简单的相机应用程序

    前言:本篇博文是本人阅读国外的IOS Programming Tutorial的一篇入门文章的学习过程总结,难度不大,因为是入门.主要是入门UIImagePickerController这个控制器,那 ...

随机推荐

  1. QuickWebApi:使用Lambada方式,完成对WebApi的开发和调用。

    QuickWebApi 目的:使用Lambada方式,完成对WebApi的开发和调用. 缘由:为了解耦服务和展现,将越来越多的使用WebApi提供各种服务:随着服务的细化,WebApi的接口将越来越多 ...

  2. linux不同环境下c/c++程序移植方法

    这边之前的大多数项目都用的java,而自己用的c++,等到快要上线的时候才发现线上机器的gcc和libc的版本都巨低,跟自己测试开发用的环境不兼容,编译出的c++可执行文件没法运行.解决c++程序的移 ...

  3. Controller的激活

    Controller的激活 概述 在此系列开篇的时候介绍了MVC的生命周期 , 对于请求的处理,都是将相应的类的方法注册到HttpApplication事件中,通过事件的依次执行从而完成对请求的处理. ...

  4. API HOOK库

    API HOOK库 API HOOK有两种做法,一种是SetWindowHookEx,简单易用,但如果做其它的HOOK,如HOOK OpenProcess,就需要修改内存地址了,内存地址可以通过Wri ...

  5. 【转】title与alt的区别

    html中的title属性和alt属性让人有些混淆. 以前不知道有title这个属性,第一次用到它时,就和alt产生了混淆.一位朋友告诉我说,alt是图片img标签里用的,title是超链接里用的,当 ...

  6. sql server DateTime相关内置函数总结

    本文部分内容参考msdn帮助文档和博客园!汇总备忘 1.获取当前日期      getdate()函数以datetime数据类型的格式返回当前SQLServer服务器所在计算机的日期和时间.其语法格式 ...

  7. 深入浅出 ThreadLocal(一)

    本文参考http://lavasoft.blog.51cto.com/62575/51926/,对其中的程序进行了改写 一.概述 ThreadLocal是什么呢?其实ThreadLocal并非是一个线 ...

  8. MongoDB安装心得

    本人纯前端一枚,对于数据库安装各种纠结,出了不少错误,一一列出,方便遇到同样问题的人给以参考,也加深一下自己印象. 故事开始了...Node.js在前端界比较火,由于我也是小小前端,跟随大潮流开始步入 ...

  9. 从零开始学C++之对象的使用(二):四种对象生存期和作用域、static 用法总结

    一.四种对象生存期和作用域 栈对象 隐含调用构造函数(程序中没有显式调用) 堆对象 隐含调用构造函数(程序中没有显式调用),要显式释放 全局对象.静态全局对象 全局对象的构造先于main函数 已初始化 ...

  10. [置顶] Java开源代码研究总结

          由于工作中的需要,最近在研究SNMP协议和利用snmp4j和snmp4j.agent(   http://www.snmp4j.org/ ),实现snmp的南向和北向功能. 结合以前看过的 ...