轉:【iOS開發每日小筆記(十一)】iOS8更新留下的「坑」 NSAttributedString設置下劃線 NSUnderlineStyleAttributeName 屬性必須爲NSNumber

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

標籤:des   class   style   代碼   html   使用   問題   文件   數據   html

這篇文章是個人【iOS開發每日小筆記】系列中的一片,記錄的是今天在開發工做中遇到的,能夠用很短的文章或很小的demo演示解釋出來的當心得小技巧。它們可能會給用戶體驗、代碼效率獲得一些提高,或是以前本身沒有接觸過的技術,很開心的學到了,放在這裏得瑟一下。90%的做用是幫助本身回顧、記憶、複習。node

 

測試組的小夥伴們大顯神威,iOS8剛發佈,他們就把測試設備急速升級了,而後就是撲面而來的各類bug和他們各類幸災樂禍的笑。沒辦法,老老實實修復bug!ios

來看看今天我遇到的一個問題:git

項目中,我將一個簡化的HTML格式的字符串讀進內存,而後以NSHTMLTextDocumentType類型爲option,初始化了一個NSAttributedString類型的實例,並將它用UITextView顯示出來。github

本來在iOS7中,顯示沒有任何問題,不管是設置顏色的地方,仍是下劃線,都徹底OK。可是升級了iOS8之後,UITextView徹底不顯示了。log裏的報錯也是讓人摸不着頭腦:api

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= =)和代碼分析,終於發現原來問題出在設置「下劃線」這個環節上。app

先來看一下個人問題代碼:測試

 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中,這樣竟是錯的!參考:ui

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

相關文章
相關標籤/搜索