Swift與C語(yǔ)言指針結(jié)合使用實(shí)例
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)
另一種常見(jiàn)的情況是Cocoa中NSError的習(xí)慣用法。許多方法會(huì)使用一個(gè)NSError**參數(shù)來(lái)儲(chǔ)存可能的錯(cuò)誤的信息。舉例來(lái)說(shuō):我們用NSFileManager的contentOfDirectoryAtPath(_: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ù)組a和b相加,并將結(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)指針類型為Array或String時(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í)的情況。
相關(guān)文章
swift實(shí)現(xiàn)簡(jiǎn)單的計(jì)算器
這篇文章主要為大家詳細(xì)介紹了swift實(shí)現(xiàn)簡(jiǎn)單的計(jì)算器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01Swift調(diào)用Objective-C編寫的API實(shí)例
這篇文章主要介紹了Swift調(diào)用Objective-C編寫的API實(shí)例,介紹的比較全面和詳細(xì),對(duì)Objective-C代碼的重復(fù)利用有極大好處,的朋友可以參考下2014-07-07swift中c風(fēng)格的for循環(huán)執(zhí)行效率
這篇文章主要介紹了swift中c風(fēng)格的for循環(huán)執(zhí)行效率 的相關(guān)資料,需要的朋友可以參考下2016-07-07詳談swift內(nèi)存管理中的引用計(jì)數(shù)
下面小編就為大家?guī)?lái)一篇詳談swift內(nèi)存管理中的引用計(jì)數(shù)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09Swift編程中的switch...case語(yǔ)句實(shí)例解析
這篇文章主要介紹了Swift編程中的switch...case語(yǔ)句實(shí)例解析,其中重點(diǎn)還是對(duì)于fallthrough關(guān)鍵字用法的講解,需要的朋友可以參考下2016-04-04Swift實(shí)現(xiàn)簡(jiǎn)易計(jì)算器功能
這篇文章主要為大家詳細(xì)介紹了Swift實(shí)現(xiàn)簡(jiǎn)易計(jì)算器功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01