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

相关推荐
season_zhu21 分钟前
iOS开发:关于URL解析
ios·json·swift
iOS大前端海猫1 小时前
深入解析 Swift 中的并发属性包装器:@Actor、@MainActor 和 @GlobalActor
ios·app
ZRD11121 小时前
SwiftUI 表达式
swiftui·swift
溪饱鱼2 小时前
DHgate爆火背后的技术原因
android·前端·ios
增强3 小时前
腾讯云 人脸核身 Flutter 插件功能开发(一 IOS 端实现)
ios
鸿蒙布道师6 小时前
鸿蒙NEXT开发图片相关工具类(ArkTs)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
Unlimitedz21 小时前
iOS内存管理中的强引用问题
macos·ios·cocoa
雨夜赶路人1 天前
iOS开发--接入ADMob广告失败
ios
旭日猎鹰1 天前
iOS崩溃堆栈分析
ios
SY.ZHOU1 天前
Flutter 与原生通信
android·flutter·ios