简单介绍 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新知",每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

相关推荐
陈皮话梅糖@10 小时前
iOS 集成ffmpeg
ios·ffmpeg
幽夜落雨11 小时前
ios老版本应用安装方法
ios
胖虎119 小时前
实现 iOS 自定义高斯模糊文字效果的 UILabel(文末有Demo)
ios·高斯模糊文字·模糊文字
_可乐无糖2 天前
Appium 检查安装的驱动
android·ui·ios·appium·自动化
胖虎13 天前
iOS 网络请求: Alamofire 结合 ObjectMapper 实现自动解析
ios·alamofire·objectmapper·网络请求自动解析·数据自动解析模型
开发者如是说3 天前
破茧英语路:我的经验与自研软件
ios·创业·推广
假装自己很用心3 天前
iOS 内购接入StoreKit2 及低与iOS 15 版本StoreKit 1 兼容方案实现
ios·swift·storekit·storekit2
iOS阿玮3 天前
“小红书”海外版正式更名“ rednote”,突然爆红的背后带给开发者哪些思考?
ios·app·apple
刘小哈哈哈3 天前
iOS UIScrollView的一个特性
macos·ios·cocoa
忆江南的博客4 天前
iOS 性能优化:实战案例分享
ios