Pointers in SWIFT are mapped to generics
Unsafepointer<t>
Unsafemutablepointer<t>
A unsafebufferpointer<t> that represents a set of continuous data pointers
An opaque pointer copaquepointer that represents a non-complete structure, and so on
Unsafepointer<t> is evaluated by the memory property, and if the pointer is a variable unsafemutablepointer<t> type, we can also assign it by memory.
| 1 2 3 5 6 7 |
func incrementor(ptr: UnsafeMutablePointer<Int>) { ptr.memory += 1 } var a = 10 incrementor(&a) a // 11 |
& in Swift can also take an address, but cannot get a pointer instance directly
| 1 2 3 4 5 6 7 8 9 Ten |
var a = 10//let ptr:UnsafeMutablePointer<Int> = &a // ‘inout Int‘ is not convertible to ‘UnsafeMutablePointer<Int>‘//let ptr2 = &a // 报错func incrementor1(inout num: Int) { num += 1} var b = 10incrementor1(&b)b // 11 |
| 1 2 3 5 6 7 |
[1,2,3] + 1 // 不报错,Playground显示一个地址值([1,2,3] + 1)[-100] // 不报错([1,2,3] + 1)[30]var array = [1,2,3]//array + 1 //报错 //let ptr:UnsafeMutableBufferPointer<Int> = array //报错 |
When using the inout operator, variables declared with Var and constants using let declarations are converted to Unsafepointer and Unsafemutablepoinger respectively
The address of an existing object cannot be taken directly in Swift, and we can still create a new Unsafemutablepointer object. Unlike the automatic memory management of other objects in Swift, the management of pointers requires that we manually request and release the memory.
| 123456789Ten One A - - the - - - + - + A at - - - - - in - |
// 将向系统申请 1 个 Int 大小的内存,并返回指向这块内存的指针var intPtr = UnsafeMutablePointer<Int>.alloc(1)// 初始化intPtr.initialize(10)var intPtr2 = intPtr.successor()intPtr2.initialize(50)// 读取值intPtr.memory // 10intPtr2.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 是第一个元素的指针var basePtr = arrayPtr.baseAddress as UnsafeMutablePointer<Int> basePtr.memory // 1basePtr.memory = 10basePtr.memory // 10 //下一个元素var nextPtr = basePtr.successor()nextPtr.memory // 2 |
Direct Action variable address withunsafepointer,withunsafepointers
| 1 2 3 4 5 6 7 |
var test = 10test = withUnsafeMutablePointer(&test, { (ptr: UnsafeMutablePointer<Int>) -> Int in ptr.memory += 1 returnptr.memory }) test // 11 |
Unsafebitcast
Unsafebitcast is a very dangerous operation, which forces a pointer-pointing memory to force a bitwise conversion to the target type. Because this conversion is done outside of the type management of Swift, the compiler cannot ensure that the resulting type is really correct, and you must know exactly what you are doing. Like what:
| 1 2 3 4 5 6 |
let arr = nsarray (object: ) let str = unsafebitcast ( Cfarraygetvalueatindex (arr, 0), cfstring. self ) str Code class= "OBJC Comments" >//"Meow" &NBSP; let arr2 = [ ] let str2 = Unsafebitcast ( Cfarraygetvalueatindex (arr2, 0), cfstring. self ) |
Because Nsarray can store arbitrary nsobject objects, when we use Cfarraygetvalueatindex to derive values from it, the result will be a unsafepointer<void>. Since we understand that the String object is stored, you can cast it directly to cfstring.
About unsafebitcast a more common usage scenario is the conversion between different types of pointers. Because the size of the pointer itself is certain, there is no fatal problem with the type of pointer being converted. This is common when collaborating with some C APIs. For example, there are many C API-required inputs that are void * and correspond to unsafepointer<void> in Swift. We can convert any pointer to unsafepointer in the following way.
| 1 2 3 4 5 6 7 8 9 Ten |
var count = 100var voidPtr = withUnsafePointer(&count, { (a: UnsafePointer<Int>) -> UnsafePointer<Void> in return unsafeBitCast(a, UnsafePointer<Void>.self)})// voidPtr 是 UnsafePointer<Void>。相当于 C 中的 void *voidPtr.memory //Void // 转换回 UnsafePointer<Int>var intPtr = unsafeBitCast(voidPtr, UnsafePointer<Int>.self)intPtr.memory //100 |
Pointers in Swift use the