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

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

Swift 與 C 語(yǔ)言指針友好合作


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

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

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

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

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

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í)慣用法。許多方法會(huì)使用一個(gè) NSError** 參數(shù)來(lái)儲(chǔ)存可能的錯(cuò)誤的信息。舉例來(lái)說(shuō):我們用 NSFileManagercontentOfDirectoryAtPath(_:error:) 方法來(lái)將目錄下的內(nèi)容列表,并將潛在的錯(cuò)誤指向一個(gè) 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(wú)法確定這個(gè)方法會(huì)不會(huì)在寫入數(shù)據(jù)前嘗試從指針中讀取數(shù)據(jù)。

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

在 C 語(yǔ)言中,數(shù)組和指針的聯(lián)系十分緊密,而 Swift 允許數(shù)組能夠作為指針使用,從而與基于數(shù)組的 C 語(yǔ)言 API 協(xié)同工作更加簡(jiǎn)單。一個(gè)固定的數(shù)組可以使用一個(gè)常量指針直接傳遞,一個(gè)變化的數(shù)組可以用 & 運(yùn)算符將一個(gè)非常量指針傳遞。就和輸入/輸出參數(shù)指針一樣。舉例來(lái)說(shuō):我們可以用 Accelerate 框架中的 vDSP_vadd 方法讓兩個(gè)數(shù)組 ab 相加,并將結(jié)果寫入第三個(gè)數(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 語(yǔ)言中用 cont char* 指針來(lái)作為傳遞字符串的基本方式。Swift 中的 String 可以被當(dāng)作一個(gè)無(wú)限長(zhǎng)度 UTF-8編碼的 const char* 指針來(lái)傳遞給方法。舉例來(lái)說(shuō):我們可以直接傳遞一個(gè)字符串給一個(gè)標(biāo)準(zhǔn) C 和 POSIX 庫(kù)方法

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

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

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

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