在Swift中指针用两个特殊的类型来描述,UnsafePointer和UnsafeMutablePointer,遵循Cocoa的原则,可以看出
不可变
与可变
的不同,当创建指针之后,可以通过指针的memory来操作指针。另外,Swift中UnsafeBufferPointer用来描述一组连续的数据指针,COpaquePointer用来描述非完整结构的不透明指针。
在函数中传递指针(指针作为函数参数进行传递)
在函数中传递指针有两种方式,一:使用
inout
关键字。二:使用Swift准备的指针类型。使用
inout
关键字:var num:Int = 10
func some(inout numb:Int){
//如果使用inout关键字,在函数体内部不需要处理指针类型,可直接操作
numb += 1
print("numb --> \(numb)")
}
some(&num)
print("num ---> \(num)")
使用Swift准备的指针类型
var num:Int = 10
func some(numb:UnsafeMutablePointer<Int>){
//如果使用Swift提供的类型,那么需要使用memory来进行操作
numb.memory += 1
print("numb --> \(numb.memory)")
}
some(&num)
print("num ---> \(num)")
需要注意的是,Swift中地址符&是不能直接使用的,只能是函数传递时才可用。
如何直接操作
虽然无法像OC或者C中那样直接通过地址符&来操作指针,但是Swift也提供了辅助的方法间接的来帮助我们来操作指针。
var i:Int = 10
i = withUnsafeMutablePointer(&i, {
(p:UnsafeMutablePointer<Int>) -> Int in
p.memory += 20
return p.memory
})
print("i value ---> \(i)")
如何使用指向数组的指针
如果只是函数传递,不可变直接传递,可变使用&符即可,如果想直接操作,那么还是需要UnsafeBufferPointer来辅助完成。
var array:[Int] = [2,1,3,4]
var arrayPtr:UnsafeMutableBufferPointer<Int> = UnsafeMutableBufferPointer<Int>(start: &array, count: array.count)
var baseArrayPtr:UnsafeMutablePointer<Int> = arrayPtr.baseAddress as UnsafeMutablePointer<Int>
var nextPtr:UnsafeMutablePointer<Int> = baseArrayPtr.successor()
var threPtr:UnsafeMutablePointer<Int> = nextPtr.successor()
print("第一个元素 \(baseArrayPtr.memory)")
print("第二个元素 \(nextPtr.memory)")
print("第三个元素 \(threPtr.memory)")
如何通过指针强制转换类型
这个操作比较危险,除非你明确预期知道类型,不然编译器是无法知道的,也就造成了非常大的不确定性。
let arr:NSArray = NSArray(object: "icepy")
let str:NSString = unsafeBitCast(arr[0],NSString.self)
print("str --- > \(str.stringByAppendingPathComponent("app"))")
创建一个指针
//创建可变指针
var i:UnsafeMutablePointer<String> = UnsafeMutablePointer<String>.alloc(10)
i.initialize("icepy")
内存管理
还有一点要注意的是,如果是属于自己手动创建的指针,Swift是不负责管理内存的,需要手动的销毁与释放。
一个UnsafeMutablePointer内存一般有三个状态:
- 内存没有被分配,null指针
- 内存进行了分配,且值还未初始化
- 内存进行了分配,且值已经初始化
var i:UnsafeMutablePointer<String> = UnsafeMutablePointer<String>.alloc(10)
i.initialize("icepy")
print("i的内存地址 \(i)")
print("i的memory \(i.memory)")
i.destroy() //销毁指针指向的对象
i.dealloc(10) //销毁指针申请的内存
i = nil