網站首頁 編程語言 正文
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
相關推薦
- 2022-05-06 golang excel數據寫入到sqlite3中
- 2022-05-17 基于Python編寫簡易文字語音轉換器_python
- 2022-07-30 jQuery?UI旋轉器部件Spinner?Widget_jquery
- 2024-02-28 UNI-APP中,swiper和tabbar結合實現滑動翻頁效果
- 2021-12-13 Linux系統創建TCP連接流程介紹_Linux
- 2022-12-09 Python命名空間與作用域深入全面詳解_python
- 2022-11-06 ASP.NET?MVC使用Log4Net記錄異常日志并跳轉到靜態頁_實用技巧
- 2022-09-03 C#中DataSet、DataTable、DataRow數據的復制方法_C#教程
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支