Swift标准库源码阅读笔记 - Array和ContiguousArray

本文通过源码分析探讨Swift的Array和ContiguousArray的实现,包括它们的区别、内存管理及常见操作(append、insert、remove、subscript)。在特定场景下,ContiguousArray可能提供更好的性能,特别是对于结构体和枚举类型。文章总结了两者在内存操作上的相似性和ContiguousArray在类型检查上的额外步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于 ContiguousArray ,这边有喵神的文章介绍的很详细了,可以先看看这个文章。

Array

接着喵神的思路,看一下 Array 以下是从源码中截取的代码片段。

public struct Array<Element>: _DestructorSafeContainer {
  #if _runtime(_ObjC)
    internal typealias _Buffer = _ArrayBuffer<Element>
  #else
    internal typealias _Buffer = _ContiguousArrayBuffer<Element>
  #endif

  internal var _buffer: _Buffer
  
  internal init(_buffer: _Buffer) {
    self._buffer = _buffer
  }
}
复制代码

if _runtime(_ObjC) 等价于 #if os(iOS) || os(macOS) || os(tvOS) || os(watchOS),从这个操作也可以看出 Swift 的野心不仅仅只是替换 Objective-C那么简单,而是往更加宽泛的方向发展。由于本次主要是研究在 iOS下的开发,所以主要看一下 _ArrayBuffer

_ArrayBuffer

去掉了注释和与类型检查相关的属性和方法。

internal typealias _ArrayBridgeStorage
  = _BridgeStorage<_ContiguousArrayStorageBase, _NSArrayCore>

internal struct _ArrayBuffer<Element> : _ArrayBufferProtocol {

  internal init() {
    _storage = _ArrayBridgeStorage(native: _emptyArrayStorage)
  }
  
  internal var _storage: _ArrayBridgeStorage
}
复制代码

可见 _ArrayBuffer 仅有一个存储属性 _storage ,它的类型 _ArrayBridgeStorage,本质上是 _BridgeStorage
_NSArrayCore 其实是一个协议,定义了一些 NSArray 的方法,主要是为了桥接 Objective-CNSArray
最主要的初始化函数,是通过 _emptyArrayStorage 来初始化 _storage

实际上 _emptyArrayStorage_EmptyArrayStorage 的实例,主要作用是初始化一个空的数组,并且将内存指定在堆上。

internal var _emptyArrayStorage : _EmptyArrayStorage {
  return Builtin.bridgeFromRawPointer(
    Builtin.addressof(&_swiftEmptyArrayStorage))
}
复制代码

_BridgeStorage

struct _BridgeStorage<NativeClass: AnyObject, ObjCClass: AnyObject> {
  
  typealias Native = NativeClass
  typealias ObjC = ObjCClass
  
  init(native: Native, bits: Int) {
    rawValue = _makeNativeBridgeObject(
      native, UInt(bits) << _objectPointerLowSpareBitShift)
  }
  
  init(objC: ObjC) {
    rawValue = _makeObjCBridgeObject(objC)
  }
  
  init(native: Native) {
    rawValue = Builtin.reinterpretCast(native)
  }
  
  internal var rawValue: Builtin.BridgeObject
复制代码

_BridgeStorage 实际上区分 是否是 class、@objc ,进而提供不同的存储策略,为上层调用提供了不同的接口,以及类型判断,通过 Builtin.BridgeObject 这个中间参数,实现不同的储存策略。

The ContiguousArray type is a specialized array that always stores its elements in a contiguous region of memory. This contrasts with Array, which can store its elements in either a contiguous region of memory or an NSArray instance if its Element type is a class or @objc protocol.

If your array’s Element type is a class or @objc protocol and you do not need to bridge the array to NSArray or pass the array to Objective-C APIs, using ContiguousArray may be more efficient and have more predictable performance than Array. If the array’s Element type is a struct or enumeration, Array and ContiguousArray should have similar efficiency.

正因为储存策略的不同,特别是在class 或者 @objc,如果不考虑桥接到 NSArray 或者调用 Objective-C,苹果建议我们使用 ContiguousArray,会更有效率。

Array 和 ContiguousArray 区别

通过一些常用的数组操作,来看看两者之间的区别。

append

ContiguousArray

public mutating func append(_ newElement: Element) {
    _makeUniqueAndReserveCapacityIfNotUnique()
    let oldCount = _getCount()
    _reserveCapacityAssumingUniqueBuffer(oldCount: oldCount)
    _appendElementAssumeUniqueAnd
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值