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