在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ iOS/ Swift 與 C 語言指針友好合作
特性(Attributes)
Access Control 權(quán)限控制的黑與白
基本運(yùn)算符(Basic Operators)
基礎(chǔ)部分(The Basics)
閉包(Closures)
擴(kuò)展
泛型參數(shù)(Generic Parameters and Arguments)
訪問控制和 protected
語句(Statements)
模式(Patterns)
WWDC 里面的那個“大炮打氣球”
關(guān)于語言參考(About the Language Reference)
語法總結(jié)(Summary of the Grammar)
嵌套類型
類型(Types)
Swift 初見(A Swift Tour)
泛型
枚舉(Enumerations)
高級運(yùn)算符
繼承
析構(gòu)過程
關(guān)于 Swift(About Swift)
訪問控制
類和結(jié)構(gòu)體
內(nèi)存安全
Swift 與 C 語言指針友好合作
協(xié)議
屬性(Properties)
可選類型完美解決占位問題
錯誤處理
字符串和字符(Strings and Characters)
聲明(Declarations)
自動引用計(jì)數(shù)
Swift 里的值類型與引用類型
表達(dá)式(Expressions)
Swift 文檔修訂歷史
造個類型不是夢-白話 Swift 類型創(chuàng)建
歡迎使用 Swift
詞法結(jié)構(gòu)(Lexical Structure)
集合類型(Collection Types)
下標(biāo)
方法(Methods)
可選鏈?zhǔn)秸{(diào)用
版本兼容性
類型轉(zhuǎn)換
構(gòu)造過程
The Swift Programming Language 中文版
函數(shù)(Functions)
Swift 教程
控制流(Control Flow)

Swift 與 C 語言指針友好合作


翻譯:老碼團(tuán)隊(duì)翻譯組-Relly 校對:老碼團(tuán)隊(duì)翻譯組-Tyrion

本頁包含內(nèi)容:

Objective-C 和 C 的 API 常常會需要用到指針。Swift 中的數(shù)據(jù)類型都原生支持基于指針的 Cocoa API,不僅如此,Swift 會自動處理部分最常用的將指針作為參數(shù)傳遞的情況。這篇文章中,我們將著眼于在 Swift 中讓 C 語言指針與變量、數(shù)組和字符串共同工作。

用以輸入/輸出的參數(shù)指針

C 和 Objective-C 并不支持多返回值,所以 Cocoa API 中常常將指針作為一種在方法間傳遞額外數(shù)據(jù)的方式。Swift 允許指針被當(dāng)作 inout 參數(shù)使用,所以你可以用符號 & 將對一個變量的引用作為指針參數(shù)傳遞。舉例來說:UIColor 中的 getRed(_:green:blue:alpha:) 方法需要四個 CGFloat* 指針來接收顏色的組成信息,我們使用 & 來將這些組成信息捕獲為本地變量:

var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
color.getRed(&r, green: &g, blue: &b, alpha: &a)

另一種常見的情況是 Cocoa 中 NSError 的習(xí)慣用法。許多方法會使用一個 NSError** 參數(shù)來儲存可能的錯誤的信息。舉例來說:我們用 NSFileManagercontentOfDirectoryAtPath(_:error:) 方法來將目錄下的內(nèi)容列表,并將潛在的錯誤指向一個 NSError? 變量:

var maybeError: NSError?
if let contents = NSFileManager.defaultManager()
    .contentsOfDirectoryAtPath("/usr/bin", error: &maybeError) {
    // Work with the directory contents
} else if let error = maybeError {
    // Handle the error
}

為了安全性,Swift 要求被使用 & 傳遞的變量已經(jīng)初始化。因?yàn)闊o法確定這個方法會不會在寫入數(shù)據(jù)前嘗試從指針中讀取數(shù)據(jù)。

作為數(shù)組使用的參數(shù)指針

在 C 語言中,數(shù)組和指針的聯(lián)系十分緊密,而 Swift 允許數(shù)組能夠作為指針使用,從而與基于數(shù)組的 C 語言 API 協(xié)同工作更加簡單。一個固定的數(shù)組可以使用一個常量指針直接傳遞,一個變化的數(shù)組可以用 & 運(yùn)算符將一個非常量指針傳遞。就和輸入/輸出參數(shù)指針一樣。舉例來說:我們可以用 Accelerate 框架中的 vDSP_vadd 方法讓兩個數(shù)組 ab 相加,并將結(jié)果寫入第三個數(shù)組 result。

import Accelerate

let a: [Float] = [1, 2, 3, 4]
let b: [Float] = [0.5, 0.25, 0.125, 0.0625]
var result: [Float] = [0, 0, 0, 0]

vDSP_vadd(a, 1, b, 1, &result, 1, 4)

// result now contains [1.5, 2.25, 3.125, 4.0625]

用作字符串參數(shù)的指針

C 語言中用 cont char* 指針來作為傳遞字符串的基本方式。Swift 中的 String 可以被當(dāng)作一個無限長度 UTF-8編碼的 const char* 指針來傳遞給方法。舉例來說:我們可以直接傳遞一個字符串給一個標(biāo)準(zhǔn) C 和 POSIX 庫方法

puts("Hello from libc")
let fd = open("/tmp/scratch.txt", O_WRONLY|O_CREAT, 0o666)

if fd < 0 {
    perror("could not open /tmp/scratch.txt")
} else {
    let text = "Hello World"
    write(fd, text, strlen(text))
    close(fd)
}

指針參數(shù)轉(zhuǎn)換的安全性

Swift 很努力地使與 C 語言指針的交互更加便利,因?yàn)樗鼈儚V泛地存在于 Cocoa 之中,同時保持一定的安全性。然而,相比你的其他 Swift 代碼與 C 語言的指針交互具有潛在的不安全性,所以務(wù)必要小心使用。其中特別要注意:

  • 如果被調(diào)用者為了在其返回值之后再次使用而保存了 C 指針的數(shù)據(jù),那么這些轉(zhuǎn)換使用起來并不安全。轉(zhuǎn)換后的指針僅在調(diào)用期間保證有效。甚至你將同樣的變量、數(shù)組或字符串作為多指針參數(shù)再次傳遞,你每次都會收到一個不同的指針。這個異常將全局或靜態(tài)地儲存為變量。你可以安全地將這段地址當(dāng)作永久唯一的指針使用。例如:作為一個 KVO 上下文參數(shù)使用的時候。

  • 當(dāng)指針類型為 ArrayString 時,溢出檢查不是強(qiáng)制進(jìn)行的。 基于 C 語言的 API 無法增加數(shù)組和字符串大小,所以在你將其傳遞到基于 C 語言的 API 之前,你必須確保數(shù)組或字符的大小正確。

如果你需要使用基于指針的 API 時沒有遵守以上指導(dǎo),或是你重寫了接受指針參數(shù)的 Cocoa 方法,于是你可以在 Swift 中直接用不安全的指針來使用未經(jīng)處理的內(nèi)存。在未來的文章中我們將著眼于更加高級的情況。