【iOS開發每日小筆記(十一)】iOS8更新留下的“坑” NSAttributedString設定底線 NSUnderlineStyleAttributeName 屬性必須為NSNumber

來源:互聯網
上載者:User

標籤:des   style   blog   http   color   io   os   使用   ar   

這篇文章是我的【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 0xae846f02014-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 0xae846f02014-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類型,改為[NSNumber numberWithInt: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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.