因爲Swift編程語言屬於上層編程語言,而Swift中因爲爲了低層的高性能計算接口,因此每每須要C語言中的指針類型,由此,在Swift編程語言剛誕生的時候就有了UnsafePointer與UnsafeMutablePointer類型,分別對應爲const Type*類型與Type *類型。算法
而在Swift編程語言中,因爲通常數組(Array)對象都沒法直接用於C語言中含有指針類型的函數參數(好比:void*),因此每每須要將數組轉爲指針類型,此外也須要將數組中元素內容存放到連續的存儲空間。此外,Swift中的字符串對象都是String結構體對象,所以也須要將它們轉換爲C語言中const char *類型相兼容的類型,所以這裏將給你們介紹一些比較簡便、且純Swift接口的使用方法,而不是藉助於Objective-C的Foundation庫。編程
/** 此函數用於將一個數組(Array)的首個元素的值作加1操做 - parameters: - p: inout [Int]類型,傳入的數組對象首地址 - returns: Void */ func test(inout p: [Int]) { p[0] += 1 } class ViewController: NSViewController { override func viewDidLoad() { super.viewDidLoad() var a = 0 // 下面使用UnsafeMutablePointer自帶的alloc類方法分配10個Int元素的存儲空間 // 這個方法其實應該就是對malloc函數的封裝了,用於外部的C接口十分有用 let buf = UnsafeMutablePointer<Int>.alloc(10) let dst = UnsafeMutablePointer<Int>.alloc(10) // 分別對buf與dst存儲空間進行初始化賦值 for i in 0 ..< 10 { buf[i] = i dst[i] = 0 } // 使用assignBackwardFrom將buf存儲空間中後5個元素拷貝到dst存儲空間的前5個元素中 dst.assignBackwardFrom(buf.advancedBy(5), count: 5) // 用Array分配一個10個Int元素的數組對象arr var arr = [Int](count: 10, repeatedValue: 0) // 將dst中的全部元素拷貝到arr中 for i in 0 ..< 10 { arr[i] = dst[i] } print(arr) // 釋放buf與dst。注意,這裏必須用dealloc來釋放,且裏面的參數也要與alloc的參數對應! // 不釋放會引起內存泄漏 buf.dealloc(10) dst.dealloc(10) // arr數組對象指向另外一個[1, 2, 3]數組字面量構成的Array對象 arr = [1, 2, 3] // 調用test函數,使得arr的第一個元素的值加1 test(&arr) print("arr = \(arr)") // 這裏使用Array的withUnsafeMutableBufferPointer方法將數組元素內容轉爲 // 指向一個連續存儲空間的首地址。 // 因此p的類型爲:UnsafeMutablePointer<Int> let p = arr.withUnsafeMutableBufferPointer() { // 這裏,形參是一個含有一個UnsafeMutableBufferPointer的形參, // 返回類型爲UnsafeMutablePointer的函數類型。 (inout buffer: UnsafeMutableBufferPointer<Int>) -> UnsafeMutablePointer<Int> in return buffer.baseAddress } a = 0 // 咱們先查看原先數組對象中的元素內容 for i in 0 ..< 3 { a += p[i] } print("a = \(a)") // 咱們經過p指針對象對數組arr的內容進行修改 p[0] -= 1 p[1] += 1 p[2] += 2 // 而後打印出修改後的arr數組對象中的元素內容 print("arr is: \(arr)") // 這裏用nulTerminatedUTF8方法先轉爲ContiguousArray<CodeUnit>對象類型, // 其中,CodeUnit是UInt8類型。 // 而後用withUnsafeBufferPointer轉爲UnsafePointer<CChar>類型 let cstr = "abcd".nulTerminatedUTF8.withUnsafeBufferPointer() { return UnsafePointer<CChar>($0.baseAddress) } // 這裏再將剛纔生成的UnsafePointer<CChar>類型的C格式字符串轉回String對象 let string = String.fromCString(cstr)! print("string is: \(string)") } }
上述代碼中,UnsafeMutablePointer的alloc方法也是個很不錯的方法,這個方法應該是直接對C語言標準庫malloc的封裝,可使得咱們方便地在Swift中分配連續的存儲空間,好比對於像圖像處理、矩陣計算等算法尤其實用。固然,若是咱們的邏輯主要用Array來處理,而後再交給底層的C語言接口作高性能計算,那麼也可使用數組對象轉連續存儲空間withUnsafeBufferPointer方法,這種處理方式在網絡數據通訊中也比較實用。數組