一道媚、介紹
Swift中的指針分為兩類, typed pointer 指定數(shù)據(jù)類型指針, raw pointer 未指定數(shù)據(jù)類型的指針 (原?指針)
raw pointer 在 Swift 中的表示是 UnsafeRawPointer
tyepd pointer 在 Swift 中的表示是 UnsafePointer<T>
二悉盆、使用
1娜亿、原始指針:RawPionter的使用
/**
RawPionter的使用
*/
//1巫糙、分配32字節(jié)的內(nèi)存空間大小
let p = UnsafeMutableRawPointer.allocate(byteCount: 32, alignment: 8)
//2摄狱、advanced代表當前 p 前進的步長而咆,對于 RawPointer 來說,我們需要移動的是當前存儲值得內(nèi)存大小即烟零,MemoryLayout.stride
//3瘪松、storeBytes: 這里就是存儲我們當前的數(shù)據(jù)咸作,這里需要制定我們當前數(shù)據(jù)的類型
for i in 0..<4{
p.advanced(by: i * 8).storeBytes(of: i + 1, as: Int.self)
}
//4、load顧明思義是加載宵睦,fromBytesOffe:是相對于我們當前 p 的首地址的偏移
for i in 0..<4{
let value = p.load(fromByteOffset: i * 8, as: Int.self)
print("index\(i),value:\(value)")
}
p.deallocate()
2记罚、Type pointer :確定類型的指針
- 第一種
//如何獲取 age 變量的地址
var age = 10
//1、通過Swift提供的簡寫的API壳嚎,這里注意當前尾隨閉包的寫法
let p = withUnsafePointer(to: &age){$0}
print(p.pointee)
//2桐智、withUnsafePointer的返回值是 unSafePointer,意味著我們不能直接修改值
var b = withUnsafePointer(to: &age){ prt in
prt.pointee += 12
}
//3诬辈、如果我們想要直接修改當前Pointer.pointee的值酵使,那么使用withUnsafeMutablePointer
withUnsafeMutablePointer(to: &age){ptr in
ptr.pointee += 10
}
print(age)
- 第二種
//1荐吉、capacity:容量大小焙糟,當前的大小為 1 * 8字節(jié)
let ptr = UnsafeMutablePointer<Int>.allocate(capacity: 1)
//2、初始化當前的UnsafeMutablePointer<Int> 指針
ptr.initialize(to: age)
//3样屠、下面兩個成對調(diào)用穿撮,管理內(nèi)存
ptr.deinitialize(count: 1)
ptr.deallocate()
3、多種方式訪問類型指針
class LJTest {
var age = 18
var name = "Swift"
init() {
}
init(age: Int, name: String) {
self.age = age
self.name = name
}
}
var t = LJTest()
var t1 = LJTest(age: 100, name: "LJ")
let ptr = UnsafeMutablePointer<LJTest>.allocate(capacity: 2)
ptr.initialize(to: t)
// 注意這里的advanced 其實就是當前要移動是i * 類型大小中的i
ptr.advanced(by: 1).initialize(to: t1)
print(MemoryLayout<LJTest>.size)
print(MemoryLayout<LJTest>.stride)
print("age : \(ptr[0].age), name : \(ptr[0].name)")
print("age : \(ptr[1].age), name : \(ptr[1].name)")
print("age : \(ptr.pointee.age), name : \(ptr.pointee.name)")
print("age : \((ptr + 1).pointee.age), name : \((ptr + 1).pointee.name)")
print("age : \(ptr.successor().pointee.age), name : \(ptr.successor().pointee.name)")
ptr.deinitialize(count: 2)
ptr.deallocate()
4痪欲、綁定
- withMemoryRebound : 臨時更改內(nèi)存綁定類型
- bindMemory(to: Capacity:) : 更改內(nèi)存綁定的類型悦穿,如果之前沒有綁定,那么就是?次綁定业踢;如果綁定過了栗柒,會被重新綁定為該類型。
- assumingMemoryBound: 假定內(nèi)存綁定知举,這?是告訴編譯器:哥們我就是這種類型瞬沦,你不要檢查我 了。
//練習(xí)demo雇锡,重構(gòu)matedata
class LJTest {
var age = 18
var name = "Swift"
}
struct HeapObject {
var kind: UnsafeRawPointer
var strongref: UInt32
var unownedRef: UInt32
}
struct lj_swift_class {
var kind: UnsafeRawPointer
var superClass: UnsafeRawPointer
var cachedata1: UnsafeRawPointer
var cachedata2: UnsafeRawPointer
var data: UnsafeRawPointer
var flags: UInt32
var instanceAddressOffset: UInt32
var instanceSize: UInt32
var flinstanceAlignMask: UInt16
var reserved: UInt16
var classSize: UInt32
var classAddressOffset: UInt32
var description: UnsafeRawPointer
}
var t = LJTest()
let ptr = Unmanaged.passUnretained(t as AnyObject).toOpaque()
let heapObjcet = ptr.bindMemory(to: HeapObject.self, capacity: 1)
let metaPtr = heapObjcet.pointee.kind.bindMemory(to: lj_swift_class.self, capacity: 1)
print(metaPtr.pointee)
指針類型的轉(zhuǎn)換
var tul = (10, "a")
func testPointer(_ p: UnsafePointer<String>){
print(p)
}
withUnsafePointer(to: &tul) { (tulPtr: UnsafePointer<(Int, String)>) in
print(tulPtr)
let rePtr = UnsafeRawPointer(tulPtr).assumingMemoryBound(to: String.self)
print(rePtr)
testPointer(rePtr)
}
//獲取結(jié)構(gòu)體重參數(shù)的地址
struct LJTest_Struct {
var age = 18
var name = "swift"
}
var t = LJTest_Struct()
func testPointer(_ p: UnsafePointer<String>){
let ptr = UnsafeMutableRawPointer(mutating: p)
ptr.storeBytes(of: p.pointee + "_LJ", as: String.self)
print(p)
}
withUnsafePointer(to: &t) { (ptr: UnsafePointer<LJTest_Struct>) in
print(ptr)
let rePtr = UnsafeRawPointer(ptr) + MemoryLayout<LJTest_Struct>.offset(of: \LJTest_Struct.name)!
print(rePtr)
testPointer(rePtr.assumingMemoryBound(to: String.self))
}
臨時修改類型
var age = 18
let ptr = withUnsafePointer(to: &age){$0}
func testPointer(_ p: UnsafePointer<UInt64>){
print(p.pointee)
let ptr = UnsafeMutablePointer(mutating: p)
ptr.pointee += 100
print(ptr.pointee)
}
ptr.withMemoryRebound(to: UInt64.self, capacity: 1) { (p: UnsafePointer<UInt64>) in
testPointer(p)
}