SWIFT 中  指针被映射为泛型

UnsafePointer<T>

UnsafeMutablePointer<T>

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

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

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

1
2
3
4
5
6
7
func incrementor(ptr: UnsafeMutablePointer<Int>) {
    ptr.memory += 1
}
  
var a = 10
incrementor(&a)
// 11

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

1
2
3
4
5
6
7
8
9
10
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
4
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  //报错

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

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

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
// 将向系统申请 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

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

unsafeBitCast

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

1
2
3
4
5
6
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。

1
2
3
4
5
6
7
8
9
10
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

转载于:https://www.cnblogs.com/Free-Thinker/p/5946901.html

Swift 中的指针使用相关推荐

  1. swift学习笔记-----swift中的指针

    swift语言为了简化,把指针隐形化了.没有像OC中那样的" * ".把底层的问题交给C语言去处理,我们可以在swift中调用C 语言来解决.当然,OC也是可以调用的. 但是在某些 ...

  2. 指针 与 swift 中的引用

    指针 如果你有 C,C++ 或者 Objective-C 语言的经验,那么你也许会知道这些语言使用指针来引用内存中的地址.一个 Swift 常量或者变量引用一个引用类型的实例与C语言中的指针类似,不同 ...

  3. 在Swift中使用C语言的指针

    点击上方蓝字关注我,了解更多咨询 Objective-C和C语言经常需要使用到指针.Swift中的数据类型由于良好的设计,使其可以和基于指针的C语言API无缝混用.同时 Swift也可以自动处理大多数 ...

  4. Swift 中使用 SQLite——打开数据库

    关于Swift中使用SQLite,接下来可能会分别从打开.增.删.改.查,几个方面来介绍SQLite的具体使用,这一篇重点介绍一下如何打开. 定义全局数据库访问句柄 /// 全局数据库访问句柄 pri ...

  5. 在Swift中如何使用C中的Struct

    swift 无法直接访问 c 语言的Struct.只能通过指针的方式访问. ///-----例子1开始------- The c Lib API : mycapi.h <code style=& ...

  6. swift中为什么要创造出可选型?

    (1)因为nil这个东西,swift中没有就是没有.  Int? 叫 整型可选型,如果不提前声明,直接赋值变量 nil会报错 . 可以将Int赋值给Int?   ,但是不能将Int?赋值给Int . ...

  7. Swift中的函数curring简介

    When you hear the word "curry", the very first thing that probably passes through your min ...

  8. swift 引用其他类_浅谈swift中闭包修饰符 weak?unowned? 或什么都不用

    浅谈swift中闭包修饰符 weak?unowned? 或什么都不用 平常的开发中,clourse是我们iOSr绕不过去的坎儿. 苹果本身也很重视闭包,像之前的一些老的target-action类型的 ...

  9. Swift中Class和Struct异同

    Swift 中类和结构体有很多共同点.共同处在于: 定义属性用于存储值 定义方法用于提供功能 定义下标操作使得可以通过下标语法来访问实例所包含的值 定义构造器用于生成初始化值 通过扩展以增加默认实现的 ...

最新文章

  1. java--面向对象(4)--黑马程序员
  2. Spring 工厂的相关的方法
  3. SQL Server代理(4/12):配置数据库邮件
  4. JS——阶乘的三种做法(正向逆向递归)
  5. php radiobutton,radiobutton怎么用
  6. 1. JanusGraph的优势
  7. linux下挂载U盘的方法
  8. 智能语音识别转文字字幕实时上屏直播系统
  9. 网站安全之存储型跨站脚本编制
  10. elasticsearch 中文分词
  11. 分享119个Android手机应用源代码总有一个是你想要的
  12. 斐讯k2p梅林忘记密码恢复出厂之后的解决办法
  13. 设置计算机系统语言,windows系统默认语言如何设置-windows系统默认语言设置方法 - 河东软件园...
  14. java虚拟机运行机制
  15. unreal engine各个版本网盘离线下载
  16. SA8155P QCOM 车载系统介绍
  17. 2020最残酷一幕终于到来:最怕大势将至,你还浑然不知
  18. Spring Boot 项目如何实现上传头像功能?
  19. 小米一元流量magisk_小米手机官方REC装面具(magisk)教程
  20. tomcat 严重: Could not contact localhost:80. Tomcat may not be running.

热门文章

  1. Mysql查看和修改时区
  2. 3分钟搞懂LSI原理
  3. Ubuntu下面Master PDF Editor背景颜色设置
  4. python错误处理
  5. EfficientNet论文阅读笔记
  6. 【机器学习】传统目标检测算法之Haar分类器
  7. 斯坦福大学机器学习第二课 “单变量线性回归”
  8. a113 智能音箱芯片方案_智能路由、智能音箱、智能面板三大网红方案:中国“芯”选择让智慧家庭体验更出色...
  9. RedHat虚拟机安装VMware Tools
  10. 雨课堂知识点总结(十七)