Swift根本语法(十七)Swift的指针实现

程序员 2024-9-20 06:07:55 81 0 来自 中国
Swift根本语法文章汇总
本文主要先容Swift的指针范例,本质也是地点,但是Swift提供专门的指针范例存储地点。
主要内容:

  • 指针范例的熟悉
  • 指针范例的利用
  • 范例转换
1、指针熟悉

Swift中也有专门的指针范例,这些都被定性为“Unsafe”(不安全的),Swift中并不会简朴的认为地点就是一个指针,而是有专门的范例举行包装。只要获取到地点就可以对数据举行无访问限制的操纵,因此是不安全的。
指针范例:
指针范例熟悉UnsafePointer< Pointee >类似于 const Pointee *UnsafeMutablePointer< Pointee >类似于 Pointee *UnsafeRawPointer类似于 const void *UnsafeMutableRawPointer类似于 void *阐明:
1、指针都是不安全的,因此都是Unsafe
2、没有Mutalbe的表现仅可读指针指向的内存,带有Mutable表现可读可写
3、< Pointee >是泛型,表现指针的范例
4、带Raw的都是不支持泛型的,以是都是void范例,范例不定
2、指针的利用

2.1 带泛型

代码:

1.png
阐明:
1、通过指针的pointee来拿到内存数据
2、依然是取地点符拿到指针,只不外须要存储到Swift提供的指针范例中
3、注意Mutable的可以举行修改
2.2 无泛型

代码:


阐明:
1、没有设置范例,须要自己设置一下范例
2、注意赋值为load和取值为storeBytes即可
2.3 通过指针遍历数组

代码:
var arr = NSArray(objects: 11, 22, 33, 44)arr.enumerateObjects { (obj, idx, stop) in    print(idx, obj)    if idx == 2 { // 下标为2就制止遍历        stop.pointee = true//指针赋值    }}阐明:

  • 这种遍历方式中stop参数着实就是一个指针范例()
  • 指针拿到自己的pointee就可以举行修改了。
3、获取指针变量

3.1 获取变量的指针

3.1.1 拿到带泛型的指针

var age = 11//带泛型指针var ptr1 = withUnsafeMutablePointer(to: &age) { $0 }var ptr2 = withUnsafePointer(to: &age) { $0 }ptr1.pointee = 22print(ptr2.pointee) // 22print(age) // 22阐明:

  • with开头的可以获取,末了一个参数是闭包表达式
withUnsafeMutablePointer方法熟悉:
@inlinable public func withUnsafeMutablePointer<T, Result>(to value: inout T, _ body: (UnsafeMutablePointer<T>) throws -> Result) rethrows -> Result阐明:
1、第一个参数传的就是指针
2、第二个参数是一个闭包表达式,获取终极的Result
3、闭包表达式的参数着实就是传入的指针
4、而且可以看到闭包表达式返回的东西就是这个withUnsafePointer返回的东西
3.1.2 拿到无泛型的指针

//无泛型指针var ptr3 = withUnsafeMutablePointer(to: &age) { UnsafeMutableRawPointer($0) }var ptr4 = withUnsafePointer(to: &age) { UnsafeRawPointer($0) }ptr3.storeBytes(of: 33, as: Int.self)print(ptr4.load(as: Int.self)) // 33print(age) // 33阐明:

  • 这里是通过无泛型指针的初始化器来设置的,传入的就是带泛型的指针,以是可以直接传入$0
3.1.3 拿到变量的指针

代码:


阐明:

  • 这里很显着ptr拿到的是person变量的地点值。指针的本意嘛,不消多言。
3.1.4 拿到对象的指针

方式一:直接获取对象地点作为指针
class Person {    var age: Int    init (age: Int) {        self.age = age    }}var person = Person(age: 18)var ptr = withUnsafePointer(to: &person) { $0 }print("变量指针:",ptr)var personPointer = UnsafeMutableRawPointer?(bitPattern: ptr)print("对象指针:",personPointer)阐明:
1、调用bitPattern初始化器,内里传入的是对象的地点,此时就可以将该地点包装成指针,也就是放到一个全局区/栈
2、由于传入的参数不肯定是正确的,以是是可失败的初始化器
方式二:通过变量获取变量内容作为指针


阐明:
1、这里传入person变量,unsafeBitCast函数就可以拿到这个变量的内容赋值给ptr
2、而且设置的范例就是UnsafeRawPointer。
3、通过这种方式就可以很方便的得到对象的堆空间地点
3.2 创建一个无指向的指针

方式一:
//方式一:var ptr = malloc(16)ptr?.storeBytes(of: 10, as: Int.self)ptr?.storeBytes(of: 20, toByteOffset: 8, as: Int.self)free(ptr)//开释内存阐明:
1、malloc创建一个空间,此时拿到的ptr的范例为:(注意肯定为可选项)
2、按照正常的添加流程举行添加。注意统共16个字节,一次性赋值只赋给了前8个字节。以是还须要再赋后8个字节,toByteOffset是偏移量
方式二:
//方式二:var ptr = UnsafeMutableRawPointer.allocate(byteCount: 16, alignment: 1)ptr.storeBytes(of: 11, as: Int.self)ptr.advanced(by: 8).storeBytes(of: 22, as: Int.self)print(ptr.load(as: Int.self)) // 11print(ptr.advanced(by: 8).load(as: Int.self)) // 22ptr.deallocate()阐明:
1、通过allocate举行创建,填入字节数和对齐数
2、advanced(by: 8)是将ptr指针偏移8个字节,而且返回一个指针。以是它得到的就是后8个字节的指针
3、末了须要通过deallcate烧毁
方式三:
//方式三:var ptr = UnsafeMutablePointer<Int>.allocate(capacity: 3)ptr.initialize(to: 11)ptr.successor().initialize(to: 22)ptr.successor().successor().initialize(to: 33)print(ptr.pointee) // 11print((ptr + 1).pointee) // 22print((ptr + 2).pointee) // 33print(ptr[0]) // 11print(ptr[1]) // 22print(ptr[2]) // 33ptr.deinitialize(count: 3)ptr.deallocate()阐明:
1、如果带有泛型创建指针,那么可以直接设置容量,这里的容量是多少个值,而非字节数
2、在设置值时,可以直接用initialize(repeating: ,count重复设置两个值,每个都是10
3、也可以用initialize()只设置第一个值
4、ptr.successor()的作用就是偏移8个字节拿到其指针
5、(ptr + 1)是指针偏移,直接偏移8个字节
6、这里ptr+1、ptr[1]等价的
7、末了须要烧毁内存
注意:无泛型指针会举行字节偏移,而不是指针偏移:如果是泛型指针,由于已经知道占用内存巨细了,以是是可以举行指针偏移的,如果优劣泛型指针,不能举行指针偏移,由于不知道一次性偏移多少
4、范例转换

第一种:非泛型指针的初始化:
var ptr = withUnsafeMutablePointer(to: &age) { UnsafeMutableRawPointer($0) }var ptr2 = withUnsafePointer(to: &age) { UnsafeRawPointer($0) }阐明:
1、泛型指针转非泛型指针可以通过非泛型指针的初始化器来设置
第二种:assumingMemoryBound:

5.png
阐明:
1、非泛型指针转泛型指针可以通过这个方法来转
第三种:unsafeBitCast:
转换时会忽略数据范例的欺压转换,不会由于数据范例的变革而改变原来的内存数据


阐明:

  • 正常的数据范例转换,会改变存储的数据
  • 通过unsafeBitCast的转换不会改变内存数据
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-10-18 20:28, Processed in 0.148553 second(s), 35 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表