SWIFT 中  指针被映射为泛型

UnsafePointer<T>

UnsafeMutablePointer<T>

表示一组连续数据指针的 UnsafeBufferPointer<T>

表示非完整结构的不透明指针 COpaquePointer 等等

UnsafePointer<T> 通过 memory 属性对其进行取值,如果这个指针是可变的 UnsafeMutablePointer<T> 类型,我们还可以通过 memory 对它进行赋值。

func incrementor(ptr: UnsafeMutablePointer<Int>) {
ptr.memory += 1
} var a = 10
incrementor(&a)
a // 11

swift中&同样可以取地址, 但无法直接获取一个指针实例

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 = 10
incrementor1(&b)
b // 11
[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 //报错

当使用inout运算符时,使用var声明的变量和使用let声明的常量被分别转换到UnsafePointer和UnsafeMutablePoinger

在 Swift 中不能直接取到现有对象的地址,我们还是可以创建新的 UnsafeMutablePointer 对象。与 Swift 中其他对象的自动内存管理不同,对于指针的管理,是需要我们手动进行内存的申请和释放的。

// 将向系统申请 1 个 Int 大小的内存,并返回指向这块内存的指针
var intPtr = UnsafeMutablePointer<Int>.alloc(1)
// 初始化
intPtr.initialize(10)
var intPtr2 = intPtr.successor()
intPtr2.initialize(50)
// 读取值
intPtr.memory // 10
intPtr2.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 // 1
basePtr.memory = 10
basePtr.memory // 10 //下一个元素
var nextPtr = basePtr.successor()
nextPtr.memory // 2

直接操作变量地址 withUnsafePointer,withUnsafePointers

var test = 10
test = withUnsafeMutablePointer(&test, { (ptr: UnsafeMutablePointer<Int>) -> Int in
ptr.memory += 1
return ptr.memory
}) test // 11

unsafeBitCast

unsafeBitCast 是非常危险的操作,它会将一个指针指向的内存强制按位转换为目标的类型。因为这种转换是在 Swift 的类型管理之外进行的,因此编译器无法确保得到的类型是否确实正确,你必须明确地知道你在做什么。比如:

let arr = NSArray(object: "meow")
let str = unsafeBitCast(CFArrayGetValueAtIndex(arr, 0), CFString.self)
str // “meow” let arr2 = ["meow2"]
let str2 = unsafeBitCast(CFArrayGetValueAtIndex(arr2, 0), CFString.self)

因为 NSArray 是可以存放任意 NSObject 对象的,当我们在使用 CFArrayGetValueAtIndex 从中取值的时候,得到的结果将是一个 UnsafePointer<Void>。由于我们很明白其中存放的是 String 对象,因此可以直接将其强制转换为 CFString。

关于 unsafeBitCast 一种更常见的使用场景是不同类型的指针之间进行转换。因为指针本身所占用的的大小是一定的,所以指针的类型进行转换是不会出什么致命问题的。这在与一些 C API 协作时会很常见。比如有很多 C API 要求的输入是 void *,对应到 Swift 中为 UnsafePointer<Void>。我们可以通过下面这样的方式将任意指针转换为 UnsafePointer。

var count = 100
var 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

Swift 中的指针使用的更多相关文章

  1. 关于Swift中的指针的那些事

    前言 在Objective-c的世界中,一切对象都是指针.它是一种运行时语言,具体指针的对象类型将会在运行时,由系统分配.这样虽然自由,但是却并不安全. Swift世界就不一样了,Swift的世界很安 ...

  2. Swift中的指针类型

    Swift编程语言为了能与Objective-C与C语言兼容,而引入了指针类型.尽管官方不建议频繁使用指针类型,但很多时候,使用指针能完成更多.更灵活的任务.比如,我们要实现一个交换两个整数值的函数的 ...

  3. Swift 中 String 与 CChar 数组的转换

    在现阶段Swift的编码中,我们还是有很多场景需要调用一些C函数.在Swift与C的混编中,经常遇到的一个问题就是需要在两者中互相转换字符串.在C语言中,字符串通常是用一个char数组来表示,在Swi ...

  4. Swift——(六)Swift中的值类型

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/twlkyao/article/details/34855597     在Swift中,结构体和枚举 ...

  5. swift 中指针的使用UnsafeMutablePointer

    在swift中已经弱化了指针的使用,可以这么使用 let s: NSRange = NSMakeRange(, ) let at = UnsafeMutablePointer<NSRange&g ...

  6. Swift中对C语言接口缓存的使用以及数组、字符串转为指针类型的方法

    由于Swift编程语言属于上层编程语言,而Swift中由于为了低层的高性能计算接口,所以往往需要C语言中的指针类型,由此,在Swift编程语言刚诞生的时候就有了UnsafePointer与Unsafe ...

  7. Swift中如何转换不同类型的Mutable指针

    在Swift中我们拥有强大高级逻辑抽象能力的同时,低级底层操作被刻意的限制了.但是有些情况下我们仍然想做一些在C语言中的hack工作,下面本猫就带大家看一看如何做这样的事. hacking is ha ...

  8. Swift基础--Swift中的异常处理

    Swift中的异常处理 OC中的异常处理:方法的参数要求传入一个error指针地址,方法执行完后,如果有错误,内部会给error赋值 Swift中的异常处理:有throws的方法,就要try起来,然后 ...

  9. Swift微博项目--Swift中通过类名字符串创建类以及动态加载控制器的实现

    Swift中用类名字符串创建类(用到了命名空间) OC中可以直接通过类名的字符串转换成对应的类来操作,但是Swift中必须用到命名空间,也就是说Swift中通过字符串获取类的方式为NSClassFro ...

随机推荐

  1. using语法糖

    资源的分类 首先说一下资源的分类: 托管资源:由CLR管理分配和释放资源 非托管资源:不受CLR管理的对象,如 文件(StreamReader,BinaryReader,DataTable,各种Str ...

  2. JAVA中遇到 UTF-八 序列的字节 1 无效

    UTF-8 序列的字节 1 无效用dom4j操作xml文件, 出现了这个错误.原因是xml文件被创建的时候是ansi码格式. (   UTF-8 序列的字节 1 无效用dom4j操作xml文件, 出现 ...

  3. Android app 简单的电话拨号器

    实现步骤: 1.画UI 可以用拖拽和文本编辑. 2.根据UI写业务逻辑  在MainActivity中的onCreate中编写 //get editText content et_number = ( ...

  4. 修复垂直滑动RecyclerView嵌套水平滑动RecyclerView水平滑动不灵敏问题

    在 Android 应用中,大部分情况下都会使用一个垂直滚动的 View 来显示内容(比如 ListView.RecyclerView 等).但是有时候你还希望垂直滚动的View 里面的内容可以水平滚 ...

  5. oracle round 函数,replace()函数

    (1)如何使用 Oracle Round 函数 (四舍五入)描述 : 传回一个数值,该数值是按照指定的小数位元数进行四舍五入运算的结果.SELECT ROUND( number, [ decimal_ ...

  6. Lobes of the brain

    Source: https://en.wikipedia.org/wiki/Lobes_of_the_brain (Except for the last figure) Terminologia A ...

  7. iTextSharp带中文转换出来的PDF文档显示乱码

    刚才有写一个小练习<Html代码保存为Pdf文件>http://www.cnblogs.com/insus/p/4323224.html.马上有网友说,当截取块有中文时,保存的pdf文件将 ...

  8. [转]ReactPHP── PHP版的Node.js

    FROM : http://www.csdn.net/article/2015-10-12/2825887 摘要:ReactPHP作为Node.js的PHP版本.在实现思路,使用方法,应用场景上的确有 ...

  9. CSS3 perspecitve属性

    M M .div1 { position: relative; height: 150px; width: 150px; margin: 0px; padding:2px; border: 1px s ...

  10. 目录结构-内置(AJAX)帮助文档

    Discuz common.js 内置(AJAX)函数帮助文档 作者:cr180 / 整理日期:1970-01-01 / 个人站点:www.cr180.com / Discuz超级管家 showMen ...