欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Swift踩坑實戰(zhàn)之一個字符引發(fā)的Crash

 更新時間:2022年02月22日 11:31:15   作者:漢森  
swift通常都是通過對應(yīng)的signal來捕獲crash,下面這篇文章主要給大家介紹了關(guān)于Swift踩坑實戰(zhàn)之一個字符引發(fā)的Crash的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下

最近因為一個字符引發(fā)了 Crash,因為實際的業(yè)務(wù)場景不便描述,這里便用一段測試代碼作說明。

話不多說,直接上代碼:

let testCharacters: Set<Character> = ["!", "\"", "$", "%", "&", "'", "+", ",", "<", "=", ">", "@", "[", "]", "`", "{", "}"]
let testString = "@`Hello World?!"
var result: UInt8 = 0
for character in testString {
    if testCharacters.contains(character) {
	result += character.asciiValue!
    }
}

上面的代碼做的事情是:取出 testString 里特定字符的 ASCII 碼,然后相加。

我們來 Review 下這段代碼,有經(jīng)驗的同學(xué)應(yīng)該立馬嗅到了代碼里的壞味道:character.asciiValue! 這里用了強解。

那這里的強解用得合理嗎?因為定義在 testCharacters 里的字符肯定都有對應(yīng)的 ASCII 碼,咋一看這里用強解也沒關(guān)系。

但是,如果我們實際跑一下,就會出現(xiàn)因為 asciiValue 為 nil 的強解 Crash 了。這是為什么呢?

關(guān)鍵在于 testString 里面包含了 全角字符。testString 里的后一個 ? 是一個全角字符,它是沒有 asciiValue 的。

我們可以在 Swift Playgrounds 里執(zhí)行下面的代碼得到答案:

let halfWidth = "`"
halfWidth.lengthOfBytes(using: .utf8) // 1
halfWidth.first!.isASCII // true
halfWidth.first!.asciiValue // 96

let fullWidth = "?"
fullWidth.lengthOfBytes(using: .utf8) // 3
fullWidth.first!.isASCII // false
fullWidth.first!.asciiValue // nil
// Character 實現(xiàn) Equatable 協(xié)議,判斷出兩個值是相等的。
halfWidth == fullWidth // true

從上面代碼執(zhí)行結(jié)果可以看到,halfWidth 這個半角字符占一個字節(jié)長度,對應(yīng)的 ASCII 碼為 96 而全角字符 fullWidth 占三個字節(jié)長度,其 asciiValue 為空的。

Swift 數(shù)組的 contains 方法利用的是 Equatable 協(xié)議 , 從上面代碼里 halfWidth == fullWidth 的結(jié)果為 true 來看,Character 實現(xiàn)的 Equatable 協(xié)議并沒有考慮字符全角/半角的情況。

用肉眼看,完全看不出字符有何不同,而 contains 方法結(jié)果為 true 也影響了我們的判斷,以為這個強解是 OK 的,稍不注意就導(dǎo)致了 Crash。

最后,從維基百科上整理了關(guān)于全角/半角的歷史知識:

在早期的計算機中,英語或拉丁字母語言使用的系統(tǒng),每一個字母或符號,都是使用一字節(jié)的空間(一字節(jié)由 8 比特組成,共256個編碼空間)來儲存;而漢語、日語及韓語文字,由于數(shù)量大大超過256個,故慣常使用兩字節(jié)來儲存一個字符。所以這原本是編碼層面的“單字節(jié)”“雙字節(jié)”的問題。

當(dāng)時的電腦使用等寬字體(如DOS、部分文字編輯器等)時,字體也就順應(yīng)這種編碼形式,將中日韓文字的寬度繪制成拉丁字母和數(shù)字的兩倍,這樣字符的編碼存儲和顯示寬度可以一一對應(yīng)起來:

  • 單字節(jié)文字 顯示成 半寬,
  • 雙字節(jié)文字 顯示成 全寬。

因此當(dāng)時的用戶就開始習(xí)慣稱中、日、韓等文字為 全角字符,而稱拉丁字母或數(shù)字為 半角字符。

但是,后來計算機的文字編碼技術(shù)已經(jīng)發(fā)生很大變化,存儲一個字符可能用一個、兩個、四個或者更多的字節(jié)。一個英文字符即使顯示為半寬,依照不同的編碼方式,并不一定是用一個字節(jié)存儲。

因此,現(xiàn)在字符編碼存儲和字符顯示寬度的已經(jīng)沒有一一對應(yīng)關(guān)系。

但是由于字符編碼和字形寬度曾經(jīng)的對應(yīng)關(guān)系,很多用戶一直習(xí)慣性地使用"全角/半角"詞匯。

因此現(xiàn)在的 全角字 可能是指:

  • 用兩個字節(jié)存儲的字符
  • ASCII(所謂半角英文和數(shù)字)以外所有的字符
  • 顯示上字身寬度為一比一正方形的字形。

總結(jié)

到此這篇關(guān)于Swift踩坑實戰(zhàn)之一個字符引發(fā)Crash的文章就介紹到這了,更多相關(guān)Swift字符引發(fā)的Crash內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • iOS Swift讀取本地json文件報錯的解決方法

    iOS Swift讀取本地json文件報錯的解決方法

    只要是app開發(fā)者都知道,從服務(wù)器端獲得的數(shù)據(jù)要不就是json格式的數(shù)據(jù),要么就是xml格式的數(shù)據(jù),而這篇文章主要給大家介紹了關(guān)于iOS Swift讀取本地json文件報錯的解決方法,需要的朋友可以參考借鑒,下面來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-11-11
  • Swift開發(fā)應(yīng)用中如何更方便地使用顏色詳解

    Swift開發(fā)應(yīng)用中如何更方便地使用顏色詳解

    這篇文章主要給大家介紹了關(guān)于Swift開發(fā)應(yīng)用中如何更方便地使用顏色的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-03-03
  • SwiftUI自定義導(dǎo)航的方法實例

    SwiftUI自定義導(dǎo)航的方法實例

    導(dǎo)航是我們平時經(jīng)常會遇到的一個需求,下面這篇文章主要給大家介紹了關(guān)于SwiftUI自定義導(dǎo)航的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-06-06
  • SwiftUI開發(fā)總結(jié)combine原理簡單示例詳解

    SwiftUI開發(fā)總結(jié)combine原理簡單示例詳解

    這篇文章主要為大家介紹了SwiftUI開發(fā)總結(jié)combine原理簡單示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • Swift實現(xiàn)JSON轉(zhuǎn)Model的方法及HandyJSON使用講解

    Swift實現(xiàn)JSON轉(zhuǎn)Model的方法及HandyJSON使用講解

    這篇文章給大家介紹了Swift實現(xiàn)JSON轉(zhuǎn)Model的方法及HandyJSON使用講解,非常不錯,具有參考借鑒價值,需要的朋友參考下吧
    2017-07-07
  • Swift設(shè)計思想Result<T>與Result<T,?E:?Error>類型解析

    Swift設(shè)計思想Result<T>與Result<T,?E:?Error>類型解析

    這篇文章主要為大家介紹了Swift設(shè)計思想Result<T>與Result<T,?E:?Error>的類型示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • Swift開發(fā)之使用UIRefreshControl實現(xiàn)下拉刷新數(shù)據(jù)及uirefreshcontrol使用

    Swift開發(fā)之使用UIRefreshControl實現(xiàn)下拉刷新數(shù)據(jù)及uirefreshcontrol使用

    本文給大家介紹使用UIRefreshControl實現(xiàn)下拉刷新數(shù)據(jù),及UIRefreshControl的使用步驟,對本文感興趣的朋友一起學(xué)習(xí)吧
    2015-11-11
  • Swift4使用GCD實現(xiàn)計時器

    Swift4使用GCD實現(xiàn)計時器

    這篇文章主要為大家詳細介紹了Swift4使用GCD實現(xiàn)計時器,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • 通過Notification.Name看Swift是如何優(yōu)雅的解決String硬編碼

    通過Notification.Name看Swift是如何優(yōu)雅的解決String硬編碼

    這篇文章主要給大家介紹了通過Notification.Name看Swift是如何優(yōu)雅的解決String硬編碼的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-08-08
  • Swift 3.1聊天界面鍵盤效果的實現(xiàn)詳解

    Swift 3.1聊天界面鍵盤效果的實現(xiàn)詳解

    這篇文章主要給大家介紹了Swift 3.1聊天界面鍵盤效果實現(xiàn)的相關(guān)資料,文中介紹的非常詳細,相信對大家的學(xué)習(xí)或者工作具有一定的參考價值,需要的朋友們下面來一起看看吧。
    2017-04-04

最新評論