Swift 中的指针使用
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)
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 中的指针使用相关推荐
- swift学习笔记-----swift中的指针
swift语言为了简化,把指针隐形化了.没有像OC中那样的" * ".把底层的问题交给C语言去处理,我们可以在swift中调用C 语言来解决.当然,OC也是可以调用的. 但是在某些 ...
- 指针 与 swift 中的引用
指针 如果你有 C,C++ 或者 Objective-C 语言的经验,那么你也许会知道这些语言使用指针来引用内存中的地址.一个 Swift 常量或者变量引用一个引用类型的实例与C语言中的指针类似,不同 ...
- 在Swift中使用C语言的指针
点击上方蓝字关注我,了解更多咨询 Objective-C和C语言经常需要使用到指针.Swift中的数据类型由于良好的设计,使其可以和基于指针的C语言API无缝混用.同时 Swift也可以自动处理大多数 ...
- Swift 中使用 SQLite——打开数据库
关于Swift中使用SQLite,接下来可能会分别从打开.增.删.改.查,几个方面来介绍SQLite的具体使用,这一篇重点介绍一下如何打开. 定义全局数据库访问句柄 /// 全局数据库访问句柄 pri ...
- 在Swift中如何使用C中的Struct
swift 无法直接访问 c 语言的Struct.只能通过指针的方式访问. ///-----例子1开始------- The c Lib API : mycapi.h <code style=& ...
- swift中为什么要创造出可选型?
(1)因为nil这个东西,swift中没有就是没有. Int? 叫 整型可选型,如果不提前声明,直接赋值变量 nil会报错 . 可以将Int赋值给Int? ,但是不能将Int?赋值给Int . ...
- Swift中的函数curring简介
When you hear the word "curry", the very first thing that probably passes through your min ...
- swift 引用其他类_浅谈swift中闭包修饰符 weak?unowned? 或什么都不用
浅谈swift中闭包修饰符 weak?unowned? 或什么都不用 平常的开发中,clourse是我们iOSr绕不过去的坎儿. 苹果本身也很重视闭包,像之前的一些老的target-action类型的 ...
- Swift中Class和Struct异同
Swift 中类和结构体有很多共同点.共同处在于: 定义属性用于存储值 定义方法用于提供功能 定义下标操作使得可以通过下标语法来访问实例所包含的值 定义构造器用于生成初始化值 通过扩展以增加默认实现的 ...
最新文章
- java--面向对象(4)--黑马程序员
- Spring 工厂的相关的方法
- SQL Server代理(4/12):配置数据库邮件
- JS——阶乘的三种做法(正向逆向递归)
- php radiobutton,radiobutton怎么用
- 1. JanusGraph的优势
- linux下挂载U盘的方法
- 智能语音识别转文字字幕实时上屏直播系统
- 网站安全之存储型跨站脚本编制
- elasticsearch 中文分词
- 分享119个Android手机应用源代码总有一个是你想要的
- 斐讯k2p梅林忘记密码恢复出厂之后的解决办法
- 设置计算机系统语言,windows系统默认语言如何设置-windows系统默认语言设置方法 - 河东软件园...
- java虚拟机运行机制
- unreal engine各个版本网盘离线下载
- SA8155P QCOM 车载系统介绍
- 2020最残酷一幕终于到来:最怕大势将至,你还浑然不知
- Spring Boot 项目如何实现上传头像功能?
- 小米一元流量magisk_小米手机官方REC装面具(magisk)教程
- tomcat 严重: Could not contact localhost:80. Tomcat may not be running.