Swift超詳細講解指針
Swift指針Unsafe Pointer
如果不是只讀,可以修改 ( 寫入 ),就加一個 Mutable,
如果沒有具體的類型( 通過泛型的方式 ),就加一個 Raw,
如果不是一個單獨的對象 ( 指向集合類型 ),就加上 buffer.
Unsafe [ Mutable ] [ Raw ] [ Buffer ] Pointer [ ]
蘋果沒有編譯保護的 [ 可變的 ] [沒有類型的] [ 是集合的 ] 指針 [< 具體的類型 >]
對照Objective-C
- swift 的
unsafeMutablePointer<T>: OC 的 T * - swift 的
unsafePointer<T>: OC 的 const T * - swift 的 unsafeRawPointer: OC 的 const void *
- swift 的 unsafeMutableRawPointer: OC 的 void *
例子
例子 1, 無類型的指針
let count = 2
let stride = MemoryLayout<Int>.stride
let alignment = MemoryLayout<Int>.alignment
let byteCount = stride * count
do {
print("Raw pointers")
let pointer = UnsafeMutableRawPointer.allocate(
byteCount: byteCount,
alignment: alignment)
// 指針的創(chuàng)建,與銷毀
defer {
// 需要手動管理,指針的內(nèi)存
pointer.deallocate()
}
// store 存值
pointer.storeBytes(of: 42, as: Int.self)
// 指針需要移動 stride,才能到達下一個指針
pointer.advanced(by: stride).storeBytes(of: 6, as: Int.self)
// (pointer+stride).storeBytes(of: 6, as: Int.self), 這個是另一種方式
// load 取值
print(pointer.load(as: Int.self))
print(pointer.advanced(by: stride).load(as: Int.self))
// 集合的指針
let bufferPointer = UnsafeRawBufferPointer(start: pointer, count: byteCount)
for (index, byte) in bufferPointer.enumerated() {
print("byte \(index): \(byte)")
}
}2, 具體類型的指針
具體類型的指針,可以通過指針的 pointee 屬性,方便的操作 load 和 store
let count = 2
let stride = MemoryLayout<Int>.stride
let alignment = MemoryLayout<Int>.alignment
let byteCount = stride * count
do {
print("Typed pointers")
let pointer = UnsafeMutablePointer<Int>.allocate(capacity: count)
pointer.initialize(repeating: 0, count: count)
// 與上面的一樣,指針的內(nèi)存,需要手動管理
defer {
pointer.deinitialize(count: count)
pointer.deallocate()
}
pointer.pointee = 42
// 因為編譯器做了優(yōu)化,指針到達下一個指針,不需要移動 stride
// 指針移動 1 ,就到了下一個指針
pointer.advanced(by: 1).pointee = 6
print( pointer.pointee )
print(pointer.advanced(by: 1).pointee)
let bufferPointer = UnsafeBufferPointer(start: pointer, count: count)
for (index, value) in bufferPointer.enumerated() {
print("value \(index): \(value)")
}
}例子 3: 通過綁定內(nèi)存,來做指針的轉(zhuǎn)化
bindMemory
let count = 2
let stride = MemoryLayout<Int>.stride
let alignment = MemoryLayout<Int>.alignment
let byteCount = stride * count
do {
print("Converting raw pointers to typed pointers")
let rawPointer = UnsafeMutableRawPointer.allocate(
byteCount: byteCount,
alignment: alignment)
defer {
rawPointer.deallocate()
}
// 這一步,將任意指針,轉(zhuǎn)化為類型指針
let typedPointer = rawPointer.bindMemory(to: Int.self, capacity: count)
typedPointer.initialize(repeating: 0, count: count)
defer {
typedPointer.deinitialize(count: count)
}
typedPointer.pointee = 42
typedPointer.advanced(by: 1).pointee = 6
// 看結(jié)果
print(typedPointer.pointee)
print(typedPointer.advanced(by: 1).pointee)
let bufferPointer = UnsafeBufferPointer(start: typedPointer, count: count)
for (index, value) in bufferPointer.enumerated() {
print("value \(index): \(value)")
}
}例子 4, 查看指針的字節(jié)
struct Demo{
let number: UInt32
let flag: Bool
}
do {
print("Getting the bytes of an instance")
var one = Demo(number: 25, flag: true)
withUnsafeBytes(of: &one) { bytes in
for byte in bytes {
print(byte)
}
}
}例子 4.1, 指針的字節(jié), 算 check sum
struct Demo{
let number: UInt32
let flag: Bool
}
do {
print("Checksum the bytes of a struct")
var one = Demo(number: 25, flag: true)
let checksum = withUnsafeBytes(of: &one) { (bytes) -> UInt32 in
return ~bytes.reduce(UInt32(0)) { $0 + numericCast($1) }
}
print("checksum", checksum) // checksum 4294967269
}checeSum 的使用,分為 checeSum 的計算與校驗
本文簡單描述 checeSum 的計算
數(shù)據(jù)塊,分為 n 個包, size 相同

拿包的字節(jié),計算 checkSum, checkSum 的大小限制在包的 size

例子 5, 獲取變量的指針
var cat = "fly"
// 返回的是,閉包中的參數(shù)
// withUnsafePointer , 把閉包里面的結(jié)果,rethrow 出去 ( 相當(dāng)于 return 出來 )
let warrior = withUnsafePointer(to: &cat, { $0 })
print(warrior.pointee)例子 6, 指向多個元素的指針
struct Cat{
var habit = "eat"
var paws = 6
var name = "load"
}
let ptr = UnsafeMutablePointer<Cat>.allocate(capacity: 2) // 指向兩個 Cat 結(jié)構(gòu)體
ptr.initialize(repeating: Cat(), count: 2)
defer{
ptr.deinitialize(count: 2)
ptr.deallocate()
}
var one = Cat()
one.paws = 8
ptr[1] = one
// 以下兩個等價
print(ptr[0])
print(ptr.pointee)
// 下面 3 個等價
print(ptr[1])
print((ptr + 1).pointee)
print(ptr.successor().pointee)例子 7: 元素組合的探索
var pair = (66, 666)
func test(ptr: UnsafePointer<Int>){
print(ptr.pointee)
print(ptr.successor().pointee)
}
withUnsafePointer(to: &pair) { (tuplePtr: UnsafePointer<(Int, Int)>) in
// 假定內(nèi)存綁定,不需要經(jīng)過內(nèi)存檢查
test(ptr: UnsafeRawPointer(tuplePtr).assumingMemoryBound(to:Int.self))
}參考了 Unsafe Swift: Using Pointers and Interacting With C
到此這篇關(guān)于Swift超詳細講解指針的文章就介紹到這了,更多相關(guān)Swift指針內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Swift中defer關(guān)鍵字推遲執(zhí)行示例詳解
這篇文章主要給大家介紹了關(guān)于Swift中defer關(guān)鍵字推遲執(zhí)行的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2018-03-03
淺談在Swift中關(guān)于函數(shù)指針的實現(xiàn)
這篇文章主要介紹了淺談在Swift中關(guān)于函數(shù)指針的實現(xiàn),是作者根據(jù)C語言的指針特性在Swifft中做出的一個實驗,需要的朋友可以參考下2015-07-07
在 Swift 中測試 UIAlertController的方法
這篇文章主要介紹了在 Swift 中測試 UIAlertController的方法的,需要的朋友可以參考下2015-10-10
Swift實現(xiàn)Selection Sort選擇排序算法的實例講解
選擇排序是一種穩(wěn)定的排序算法,且實現(xiàn)代碼通常比冒泡排序要來的簡單,這里我們就來看一下Swift實現(xiàn)Selection Sort選擇排序的實例講解2016-07-07

