为何每次调用processUnsafeRawPointer(key)结果不同?String传UnsafeRawPointer解析
关于Swift中UnsafeRawPointer与String传递的问题
代码与输出
示例代码
var key = "Key" func jump() { print("\ntest UnsafeRawPointer") processUnsafeRawPointer(key) processUnsafeRawPointer(&key) } func processUnsafeRawPointer(_ key: UnsafeRawPointer) { print(key) } public static func main() { jump() jump() jump() }
控制台输出
test UnsafeRawPointer 0x0000600000c104a0 0x000000010000d3c0 test UnsafeRawPointer 0x0000600000c104a0 0x000000010000d3c0 test UnsafeRawPointer 0x0000600000c18020 0x000000010000d3c0
问题解答
1. 为什么processUnsafeRawPointer(key)的打印结果会变化?
Swift的String是值类型,但底层依赖引用类型的存储结构。当直接把String传给UnsafeRawPointer参数时,Swift会临时分配一块UTF-8编码的字节缓冲区,用来存放字符串的内容,传递给方法的指针就是这块缓冲区的起始地址。
这块临时缓冲区的生命周期仅局限于当前函数调用:processUnsafeRawPointer执行完毕后,Swift会自动释放它。每次调用时,系统会根据当前内存分配情况决定缓冲区的位置,可能复用之前的内存地址,也可能分配新的地址,所以你会看到指针值有时相同、有时不同。
2. 直接传递String给接收UnsafeRawPointer的方法会发生什么?
- 自动临时缓冲区创建:Swift会自动将
String转换为UTF-8编码的临时字节缓冲区,把缓冲区的起始地址作为UnsafeRawPointer传入方法。 - 缓冲区生命周期有限:临时缓冲区仅在当前方法调用期间有效,方法执行完成后立即被释放。如果在方法外保存这个指针并后续访问,会触发野指针错误,导致未定义行为。
- 指针地址不固定:由于缓冲区是每次调用时临时分配的,内存地址可能随每次调用变化,无法保证一致性。
补充:为什么processUnsafeRawPointer(&key)的指针值固定?
&key传递的是变量key本身的内存地址(这里key是全局变量,存储在静态内存区域),这个地址在程序运行期间是固定不变的,所以每次打印的指针值都一致。
内容的提问来源于stack exchange,提问作者Yasic
相关产品推荐
相关产品推荐

