今天我们通过查看内存、汇编以及 Swift 源码等多途径来探究一下 Swift 中的 String 的内存布局及底层实现。
空字符串
首先创建一个最简单的字符串,空字符串str1:

从图中可以看到,String 内部有个 _StringGuts,_StringGuts 内部有个 _StringObject,_StringObject 内部有个 Builtin.BridgeObject 类型的_object 和一个 UInt64 类型的 _countAndFlagsBits。
找到 StringGuts 源码,可以看到 _StringGuts 是一个结构体,里面有个 _StringObject 类型的成员 _object,跟上面 Xcode 打印的一致。

搜索关键词 empty,可以轻松找到创建空字符串的初始化方法:调用 _StringObject的方法empty:() 生成一个空的 _StringObject 对象后传入到自身默认初始化方法:init(_ object: _StringObject) 中。
进一步查看 StringObject 源码,同样搜索关键词 empty,找到方法:init(empty:())。因为我们的设备是64位,所以这个方法会进入到第一个分支中,分别初始化成员:_countAndFlagsBits 和 _object(也跟图一的打印保持一致)。

Nibbles 是个枚举,源码中给它加了多个extension。进一步查看源码可以看到 Nibbles.emptyString,调用方法:small(isASCII: Bool)
enum Nibbles {}
extension _StringObject.Nibbles {
// The canonical empty string is an empty small string
@inlinable @inline(__always)
internal static var emptyString: UInt64 {
return _StringObject.Nibbles.small(isASCII: true)
}
}
extension _StringObject.Nibbles {
// Discriminator for small str

最低0.47元/天 解锁文章
568





