日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Swift超詳細講解指針_Swift

作者:dengjiangszhan ? 更新時間: 2022-09-27 編程語言

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)
    // 指針的創建,與銷毀
  defer {
     // 需要手動管理,指針的內存
    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)
  // 與上面的一樣,指針的內存,需要手動管理
  defer {
    pointer.deinitialize(count: count)
    pointer.deallocate()
  }
  pointer.pointee = 42
   // 因為編譯器做了優化,指針到達下一個指針,不需要移動 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: 通過綁定內存,來做指針的轉化

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()
  }
  // 這一步,將任意指針,轉化為類型指針
  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
   // 看結果
  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, 查看指針的字節

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, 指針的字節, 算 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 的計算

數據塊,分為 n 個包, size 相同

拿包的字節,計算 checkSum, checkSum 的大小限制在包的 size

例子 5, 獲取變量的指針

var cat = "fly"
// 返回的是,閉包中的參數
// withUnsafePointer , 把閉包里面的結果,rethrow 出去 ( 相當于 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 結構體
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
    // 假定內存綁定,不需要經過內存檢查
    test(ptr: UnsafeRawPointer(tuplePtr).assumingMemoryBound(to:Int.self))
}

參考了 Unsafe Swift: Using Pointers and Interacting With C

原文鏈接:https://blog.csdn.net/dengjiangszhan/article/details/125282552

欄目分類
最近更新