简单介绍 swift 中的指针和使用

这里每天分享一个 iOS 的新知识,快来关注我吧

喜欢我可以帮我投个票

前言

Swift 中的内存管理基于自动引用计数 (ARC),一般来说不需要我们手动操作内存。但是,除了 ARC 之外,Swift 还支持手动内存管理,这就需要手动操作内存指针了,今天就来讲讲这块儿内容。

swift 中的指针

操作内存指针被苹果认为是不安全的,且不推荐直接操作,因此关于指针的类型基本都是以 UnSafe 开头的,比如:

  • UnsafePointer

  • UnsafeMutablePointer

  • UnsafeBufferPointer

  • UnsafeMutableBufferPointer

  • UnsafeRawPointer

  • UnsafeMutableRawPointer

  • UnsafeRawBufferPointer

  • UnsafeMutableRawBufferPointer

接下来我们详细解释一下这些指针的用法。

UnsafePointer<T>

UnsafePointer<T>是一个指向类型 T 的不可变指针。它用于访问和操作内存中的数据,但不能修改数据本身,所以初始化的时候只能通过直接向它传递一个已经初始化的对象来进行。

读取指针指向的值只需要使用 pointee 属性

ini 复制代码
var array: [Int] = [1, 2, 3, 4, 5]
let pointer = UnsafePointer<[Int]>(&array)
print(pointer.pointee) // 打印 [1, 2, 3, 4, 5]

UnsafeMutablePointer<T>

UnsafeMutablePointer<T>是一个指向类型 T 的可变指针。它用于访问和修改内存中的数据,和 UnsafePointer 的区别是可以修改。

ini 复制代码
var value = 10
let pointer = UnsafeMutablePointer<Int>(&value)

pointer.pointee = 20
print(value) // 打印 20

UnsafeBufferPointer<T>

UnsafeBufferPointer<T>是一个用于访问连续内存块中元素的不可变指针。它提供了对内存块的访问和遍历,因为 UnsafeBufferPointer 实现了 Collection,所以可以使用 forEach 等高阶函数。

php 复制代码
var array: [Int] = [1, 2, 3, 4, 5]
let bufferPointer = UnsafeBufferPointer(start: array, count: array.count)

bufferPointer.forEach { value in
    print(value)
}

UnsafeMutableBufferPointer<T>

UnsafeMutableBufferPointer<T>是一个用于访问连续内存块中元素的可变指针。它提供了对内存块的访问和修改,与 UnsafeBufferPointer 不同的是,它可以修改。

php 复制代码
var array: [Int] = [1, 2, 3, 4, 5]
let bufferPointer = UnsafeMutableBufferPointer(start: &array, count: array.count)

for i in bufferPointer.startIndex..<bufferPointer.endIndex {
    bufferPointer[i] += 1
}

print(array) // 打印 [2, 3, 4, 5, 6]

UnsafeRawPointer

UnsafeRawPointer 是一个指向原始内存的不可变指针。它可以用于访问和操作任意类型的内存数据。

scss 复制代码
var value = 10
let pointer = UnsafeRawPointer(&value)

let intValue = pointer.load(as: Int.self)
print(intValue) // 打印 10

UnsafeMutableRawPointer

UnsafeMutableRawPointer 是一个指向原始内存的可变指针。它可以用于访问和操作任意类型的内存数据。申请内存的时候可以指定大小和对齐方式:

swift 复制代码
let size = MemoryLayout<Int>.size
let alignment = MemoryLayout<Int>.alignment
let pointer = UnsafeMutableRawPointer.allocate(byteCount: 8, alignment: alignment)
pointer.storeBytes(of: 32, as: Int.self)
let value = pointer.load(as: Int.self)
print(value) // 打印 32

解释下代码:

首先使用 allocate 方法创建了一个指向未初始化内存的 UnsafeMutableRawPointer 对象。byteCount 参数指定了要分配的字节数,这里是 Int 的 8 字节,alignment 参数指定了 Int 的对齐方式。

pointer.storeBytes 这一行代码将值 32 存储到 pointer 指向的内存中。storeBytes 方法用于将值存储到指定内存地址中,as 参数指定了要存储的值的类型,这里传 Int

pointer.load 这一行代码从 pointer 指向的内存中加载一个 Int 类型的值,并将其赋值给 value 变量。load 方法用于从指定内存地址中加载值,as 参数指定了要加载的值的类型,因此最终打印结果是 32。

UnsafeRawBufferPointer

UnsafeRawBufferPointer 是一个用于访问连续原始内存块中数据的不可变指针。同样实现了 Collection 协议,提供了对内存块的访问和遍历。

php 复制代码
var array: [Int] = [1, 2, 3, 4, 5]
let bufferPointer = UnsafeRawBufferPointer(start: &array, count: array.count * MemoryLayout<Int>.size)
bufferPointer.forEach { value in
    print(value)
}

UnsafeMutableRawBufferPointer

UnsafeMutableRawBufferPointer 是一个用于访问连续原始内存块中数据的可变指针。它可以修改内存块。

scss 复制代码
let pointer = UnsafeMutableRawBufferPointer.allocate(byteCount: 3, alignment: MemoryLayout<Int>.alignment)
pointer.copyBytes(from: [1, 2, 3])
pointer.forEach {
    print($0) // 打印 1, 2, 3
}

这里每天分享一个 iOS 的新知识,快来关注我吧

本文同步自微信公众号 "iOS新知",每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

相关推荐
RickeyBoy7 小时前
解决 Swift Testing 中 DI 容器的竞态条件
ios
2501_915918419 小时前
苹果App Store上架审核卡住原因分析与解决方案指南
android·ios·小程序·https·uni-app·iphone·webview
开心就好20259 小时前
不依赖 Mac 也能做 iOS 开发?跨设备开发流程
后端·ios
开心就好202510 小时前
Windows 上传 IPA 到 App Store 的步骤讲解
后端·ios
for_ever_love__12 小时前
Objective- C学习: 手动内存管理
c语言·学习·ios·objective-c
风启新尘17 小时前
ios巨魔越狱
支持向量机·ios·智能手机
Digitally17 小时前
没有充电器,如何给 iPhone 充电?
ios·iphone
bcbnb17 小时前
基于Mach-O文件的动态库与静态库归属方案及API扫描实践
后端·ios
Aurora41917 小时前
Compose的事件分发
客户端
2501_9159214318 小时前
VSCode 写 Swift 运行到 iPhone?快蝎 IDE 开发实战体验
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程