Swift 中的指针使用
SWIFT 中 ?指針被映射為泛型?
UnsafePointer<T>?
UnsafeMutablePointer<T>
表示一組連續(xù)數(shù)據(jù)指針的 UnsafeBufferPointer<T>
表示非完整結(jié)構(gòu)的不透明指針 COpaquePointer 等等
?
UnsafePointer<T>?通過(guò) memory 屬性對(duì)其進(jìn)行取值,如果這個(gè)指針是可變的 UnsafeMutablePointer<T> 類(lèi)型,我們還可以通過(guò) memory 對(duì)它進(jìn)行賦值。
| 1 2 3 4 5 6 7 | func incrementor(ptr: UnsafeMutablePointer<Int>) { ????ptr.memory += 1 } ?? var a = 10 incrementor(&a) a? // 11 |
swift中&同樣可以取地址, 但無(wú)法直接獲取一個(gè)指針實(shí)例
| 1 2 3 4 5 6 7 8 9 10 | var a = 10 //let ptr:UnsafeMutablePointer<Int> = &a // 'inout Int' is not convertible to 'UnsafeMutablePointer<Int>' //let ptr2 = &a????????????????????????? // 報(bào)錯(cuò) func incrementor1(inout num: Int) { ????num += 1 } ? var b = 10 incrementor1(&b) b?? // 11 |
| 1 2 3 4 5 6 7 | [1,2,3] + 1? // 不報(bào)錯(cuò),Playground顯示一個(gè)地址值 ([1,2,3] + 1)[-100]? // 不報(bào)錯(cuò) ([1,2,3] + 1)[30] ? var array = [1,2,3] //array + 1???? //報(bào)錯(cuò) ?//let ptr:UnsafeMutableBufferPointer<Int> = array? //報(bào)錯(cuò) |
?當(dāng)使用inout運(yùn)算符時(shí),使用var聲明的變量和使用let聲明的常量被分別轉(zhuǎn)換到UnsafePointer和UnsafeMutablePoinger
?
?在 Swift 中不能直接取到現(xiàn)有對(duì)象的地址,我們還是可以創(chuàng)建新的 UnsafeMutablePointer 對(duì)象。與 Swift 中其他對(duì)象的自動(dòng)內(nèi)存管理不同,對(duì)于指針的管理,是需要我們手動(dòng)進(jìn)行內(nèi)存的申請(qǐng)和釋放的。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | // 將向系統(tǒng)申請(qǐng) 1 個(gè) Int 大小的內(nèi)存,并返回指向這塊內(nèi)存的指針 var intPtr = UnsafeMutablePointer<Int>.alloc(1) // 初始化 intPtr.initialize(10) var intPtr2 = intPtr.successor() intPtr2.initialize(50) // 讀取值 intPtr.memory?? // 10 intPtr2.memory?? // 20 ? //intPtr.dealloc(1) //intPtr.destroy(1)// intPtr.destroy() intPtr2 = nil //intPtr2.memory? // 奔潰 ? ? ? var array = [1,2,3] let arrayPtr = UnsafeMutableBufferPointer<Int>(start: &array, count: array.count) // baseAddress 是第一個(gè)元素的指針 var basePtr = arrayPtr.baseAddress as UnsafeMutablePointer<Int> ? basePtr.memory // 1 basePtr.memory = 10 basePtr.memory // 10 ? //下一個(gè)元素 var nextPtr = basePtr.successor() nextPtr.memory // 2 |
?直接操作變量地址?withUnsafePointer,withUnsafePointers
| 1 2 3 4 5 6 7 | var test = 10 test = withUnsafeMutablePointer(&test, { (ptr: UnsafeMutablePointer<Int>) -> Int in ????ptr.memory += 1 ????return ptr.memory }) ? test // 11 |
?
unsafeBitCast
unsafeBitCast 是非常危險(xiǎn)的操作,它會(huì)將一個(gè)指針指向的內(nèi)存強(qiáng)制按位轉(zhuǎn)換為目標(biāo)的類(lèi)型。因?yàn)檫@種轉(zhuǎn)換是在 Swift 的類(lèi)型管理之外進(jìn)行的,因此編譯器無(wú)法確保得到的類(lèi)型是否確實(shí)正確,你必須明確地知道你在做什么。比如:
| 1 2 3 4 5 6 | let arr = NSArray(object: "meow") let str = unsafeBitCast(CFArrayGetValueAtIndex(arr, 0), CFString.self) str // “meow” ? let arr2 = ["meow2"] let str2 = unsafeBitCast(CFArrayGetValueAtIndex(arr2, 0), CFString.self) |
?
因?yàn)?NSArray 是可以存放任意 NSObject 對(duì)象的,當(dāng)我們?cè)谑褂?CFArrayGetValueAtIndex 從中取值的時(shí)候,得到的結(jié)果將是一個(gè) UnsafePointer<Void>。由于我們很明白其中存放的是 String 對(duì)象,因此可以直接將其強(qiáng)制轉(zhuǎn)換為 CFString。
關(guān)于 unsafeBitCast 一種更常見(jiàn)的使用場(chǎng)景是不同類(lèi)型的指針之間進(jìn)行轉(zhuǎn)換。因?yàn)橹羔槺旧硭加玫牡拇笮∈且欢ǖ?#xff0c;所以指針的類(lèi)型進(jìn)行轉(zhuǎn)換是不會(huì)出什么致命問(wèn)題的。這在與一些 C API 協(xié)作時(shí)會(huì)很常見(jiàn)。比如有很多 C API 要求的輸入是 void *,對(duì)應(yīng)到 Swift 中為 UnsafePointer<Void>。我們可以通過(guò)下面這樣的方式將任意指針轉(zhuǎn)換為 UnsafePointer。
| 1 2 3 4 5 6 7 8 9 10 | var count = 100 var voidPtr = withUnsafePointer(&count, { (a: UnsafePointer<Int>) -> UnsafePointer<Void> in ????return unsafeBitCast(a, UnsafePointer<Void>.self) }) // voidPtr 是 UnsafePointer<Void>。相當(dāng)于 C 中的 void * voidPtr.memory //Void ? // 轉(zhuǎn)換回 UnsafePointer<Int> var intPtr = unsafeBitCast(voidPtr, UnsafePointer<Int>.self) intPtr.memory //100 |
?
轉(zhuǎn)載于:https://www.cnblogs.com/Free-Thinker/p/5946901.html
總結(jié)
以上是生活随笔為你收集整理的Swift 中的指针使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 过滤器的概念与使用
- 下一篇: c# SQL CLR 之一