目录


1. Swift中的指针介绍

指针类型在Swift里被struct UnsafePointer<Memory>表示,它是一个拥有泛型的struct。它还有一个变体struct UnsafeMutablePointer<Memory>UnsafePointer 对应的是C中的常量指针(例如const char *),其他可变指针对应的是UnsafeMutablePointer

我们先来看看UnsafePointer在Apple中的定义:

struct UnsafePointer&ltMemory&gt: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.

它有三种状态:

  1. 内存未分配(例如,pointer 值是null,或者内存被释放了);
  2. 内存分配,但是值未被初始化;
  3. 内存分配,值被初始化。

只有第三种情况的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的COpaguqePointerCFunctionPointer 自由转换

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

上述例子对UnsafeMutablePointerdebugDescription(), hashValue, successor(), predecessor(), distanceTo(), move(), initializeFrom()等方法的用法进行了简单的介绍。

3 总结

UnsafeMutablePointer涉及手动内存管理,具体体现在4个主要方法alloc(), initialize(), 与destroy(), dealloc()的成对出现上;它可以与C的COpaguqePointerCFunctionPointer自由转换;它的属性和方法有debugDescription(), hashValue, successor(), predecessor(), distanceTo(), move(), initializeFrom()UnsafeMutablePointer一般不用,正如其名Unsafe, 会带来一定的安全问题。如果碰到一定要用的情况,要注意上述几点。


Share Post

Twitter Google+

Shunmian

The only programmers in a position to see all the differences in power between the various languages are those who understand the most powerful one.