目录
1. Swift中的指针介绍
指针类型在Swift里被struct UnsafePointer<Memory>
表示,它是一个拥有泛型的struct。它还有一个变体struct UnsafeMutablePointer<Memory>
。UnsafePointer
对应的是C中的常量指针(例如const char *
),其他可变指针对应的是UnsafeMutablePointer
。
我们先来看看UnsafePointer
在Apple中的定义:
struct UnsafePointer<Memory>:A pointer to an object of type Memory. This type provides no automated memory management, and therefore the user must take care to allocate and freee memory appropriately.
它有三种状态:
- 内存未分配(例如,pointer 值是null,或者内存被释放了);
- 内存分配,但是值未被初始化;
- 内存分配,值被初始化。
只有第三种情况的pointer才能正常使用。
UnsafeMutablePointer
在Apple中的定义定义和UnsafePointer
一样,是其可变类型。我们下面主要介绍UnsafeMutablePointer
。
2. UnsafeMutablePointer 例子
2.1 例1: 基础
下面是Objective-C的NSArray
1
2
3
4
5
6
7
/*NSArray is class, reference type*/
NSMutableArray *array1 = [@[@1, @2, @3] mutableCopy];
NSMutableArray *array2 = array1;
[array2 insertObject:@4 atIndex:3];
NSLog(@"%@", array1); //@[@1,@2,@3,@4]
NSLog(@"%@", array2); //@[@1,@2,@3,@4],array2&array1 point to the same objects
下面是Swift的Array
1
2
3
4
5
6
7
/*Array is struct, value type*/
var a = [1,2,3]
var b = a
b.append(4)
a //[1,2,3]
b //[1,2,3,4]
从上述例子可以看出Swift的UnsafeMutalbePointer
可以和C的COpaguqePointer
与CFunctionPointer
自由转换
2.3 例3: 地址操作
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/*UnsafeMutablePointer的绝对地址*/
let aInt = UnsafeMutablePointer<Int>.alloc(1)
aInt.initialize(10)
let bInt = UnsafeMutablePointer<Int>.alloc(1)
bInt.initialize(100)
aInt.debugDescription //memory address as string
aInt.hashValue //memory address as integer
bInt.debugDescription
bInt.hashValue
bInt.successor().debugDescription
bInt.successor().hashValue
bInt.predecessor().debugDescription
bInt.predecessor().hashValue
bInt.distanceTo(aInt) //memory address distance, -249200
let c = bInt.move() //return bInt.memory and destroy bInt
bInt.initialize(100)
/*UnsafeMutablePointer的绝相对地址*/
var cInt = aInt.advancedBy(3) // advance by sizeOf(Int) * 3 = 24
cInt.debugDescription
bInt.distanceTo(cInt) // -249197
/*多个UnsafeMutablePointer指向同一个地址*/
let hashV = bInt.hashValue
var dInt = UnsafeMutablePointer<Int>(bitPattern: hashV) //dInt 和 bInt指向同一个地址
bInt.memory = 36
dInt.memory //36
bInt.destroy()
bInt.dealloc(1) //now dInt is nil
/*UnsafeMutablePointer从另一个变量copy*/
var eInt = UnsafeMutablePointer<Int>.alloc(1)
eInt.initialize(40)
var fInt = UnsafeMutablePointer<Int>.alloc(1)
fInt.initializeFrom(eInt, count: 1) //initialize by copy deferenced value from eInt
fInt.memory //40
上述例子对UnsafeMutablePointer
的debugDescription()
, hashValue
, successor()
, predecessor()
, distanceTo()
, move()
, initializeFrom()
等方法的用法进行了简单的介绍。
3 总结
UnsafeMutablePointer
涉及手动内存管理,具体体现在4个主要方法alloc()
, initialize()
, 与destroy()
, dealloc()
的成对出现上;它可以与C的COpaguqePointer
与CFunctionPointer
自由转换;它的属性和方法有debugDescription()
, hashValue
, successor()
, predecessor()
, distanceTo()
, move()
, initializeFrom()
。UnsafeMutablePointer
一般不用,正如其名Unsafe, 会带来一定的安全问题。如果碰到一定要用的情况,要注意上述几点。