init() 函数

Array

  public init() {
_buffer = _Buffer()
}

Buffer_ContiguousArrayBuffer 为例。
即初始化了一个_ContiguousArrayBuffer

_ContiguousArrayBuffer

  /// Create an empty buffer.
@inlinable
internal init() {
_storage = _emptyArrayStorage
}

其中 _emptyArrayStorage 是一个__EmptyArrayStorage类的实例,对于所有的空数组,返回的都是同一个地址。

/// The empty array prototype.  We use the same object for all empty
/// `[Native]Array<Element>`s.
@inlinable
internal var _emptyArrayStorage : __EmptyArrayStorage {
return Builtin.bridgeFromRawPointer(
Builtin.addressof(&_swiftEmptyArrayStorage))
}

_swiftEmptyArrayStorage 定义如下:

SWIFT_RUNTIME_STDLIB_API
swift::_SwiftEmptyArrayStorage swift::_swiftEmptyArrayStorage = {
// HeapObject header;
{
&swift::CLASS_METADATA_SYM(s19__EmptyArrayStorage), // isa pointer
}, // _SwiftArrayBodyStorage body;
{
0, // int count;
1 // unsigned int _capacityAndFlags; 1 means elementTypeIsBridgedVerbatim
}
};

init(repeatedValue, count) 方法

根据元素类型,初始化_ContiguousArrayStorage类,并在堆上空间,类的尾部分配若干内存,用于存储元素。
然后使用传入的value,从头初始化内存。

  public init(repeating repeatedValue: Element, count: Int) {
var p: UnsafeMutablePointer<Element>
(self, p) = Array._allocateUninitialized(count)
for _ in 0..<count {
p.initialize(to: repeatedValue)
p += 1
}
}
  internal static func _allocateUninitialized(
_ count: Int
) -> (Array, UnsafeMutablePointer<Element>) {
let result = Array(_uninitializedCount: count)
return (result, result._buffer.firstElementAddress)
}

init<S: Sequence>(_ s: S) 方法

  public init<S: Sequence>(_ s: S) where S.Element == Element {
self = Array(
_buffer: _Buffer(
_buffer: s._copyToContiguousArray()._buffer,
shiftedToStartIndex: 0))
}

Sequence 转为ContiguousArray,然后再转为Array

internal func _copySequenceToContiguousArray<
S : Sequence
>(_ source: S) -> ContiguousArray<S.Element> {
let initialCapacity = source.underestimatedCount
var builder =
_UnsafePartiallyInitializedContiguousArrayBuffer<S.Element>(
initialCapacity: initialCapacity) var iterator = source.makeIterator() // FIXME(performance): use _copyContents(initializing:). // Add elements up to the initial capacity without checking for regrowth.
for _ in 0..<initialCapacity {
builder.addWithExistingCapacity(iterator.next()!)
} // Add remaining elements, if any.
while let element = iterator.next() {
builder.add(element)
} return builder.finish()
}

其中用到了Sequenceiterator
在遍历过程中,可能会存在内存不够,需要重新分配内存。

  /// Add an element to the buffer, reallocating if necessary.
@inlinable
@inline(__always) // For performance reasons.
internal mutating func add(_ element: Element) {
if remainingCapacity == 0 {
// Reallocate.
let newCapacity = max(_growArrayCapacity(result.capacity), 1)
var newResult = _ContiguousArrayBuffer<Element>(
_uninitializedCount: newCapacity, minimumCapacity: 0)
p = newResult.firstElementAddress + result.capacity
remainingCapacity = newResult.capacity - result.capacity
if !result.isEmpty {
// This check prevents a data race writting to _swiftEmptyArrayStorage
// Since count is always 0 there, this code does nothing anyway
newResult.firstElementAddress.moveInitialize(
from: result.firstElementAddress, count: result.capacity)
result.count = 0
}
(result, newResult) = (newResult, result)
}
addWithExistingCapacity(element)
}

分配内存时,大小是指数级增长。

@inlinable
internal func _growArrayCapacity(_ capacity: Int) -> Int {
return capacity * 2
}

Swift 里 Array (二)初始化的更多相关文章

  1. Swift 里 Array (一)内存结构

    public struct Array<Element>: _DestructorSafeContainer { #if _runtime(_ObjC) @usableFromInline ...

  2. Swift 里 Array (四) Accessing Elements

    根据下标取值 关键代码如下: func _getElement( _ index: Int, wasNativeTypeChecked: Bool, matchingSubscriptCheck: _ ...

  3. Swift 里 Array (三) Inspecting an Array

    判断是否为空 使用的是Collection协议里isEmpty的判断. public var isEmpty: Bool { return startIndex == endIndex } start ...

  4. swift学习(二)--基本运算符、字符串、集合操作

    在这一篇博客里面,我想要介绍一下swift里面一些常用的基本运算符,还有涉及到的字符串,集合操作.你会发现在swift里面还是有许多其他语言所不具有的特性运算操作的. 首先最基本的+,-,*,/,&g ...

  5. [Swift]数组(Array)最强解析

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  6. Swift中文教程(二)--简单值

    原文:Swift中文教程(二)--简单值 Swift使用let关键字声明常量,var关键字声明变量.常量无需在编译时指定,但至少要被赋值一次.也就是说,赋值一次多次使用: var myVariable ...

  7. Swift里performSelector方法的替代

    最近在回答StackOverflow的问题时,发现performSelector方法在Swift被去掉,Apple的注释是这个方法被去掉是因为不安全: NOTE The performSelector ...

  8. Swift 学习之二十一:?和 !(详解)

    http://blog.csdn.net/woaifen3344/article/details/30244201 Swift语言使用var定义变量,但和别的语言不同,Swift里不会自动给变量赋初始 ...

  9. iOS开发Swift篇—(二)变量和常量

    iOS开发Swift篇—(二)变量和常量 一.语言的性能 (1)根据WWDC的展示 在进行复杂对象排序时Objective-C的性能是Python的2.8倍,Swift的性能是Python的3.9倍 ...

随机推荐

  1. unity的三种update

    void FixedUpdate () 固定更新 void Update ()        更新 void LateUpdate()  晚于更新 FixedUpdate () 和 Update () ...

  2. HTML 内 meta标签

    <!-- 是否删除默认的苹果工具栏和菜单栏 --> <meta name="apple-mobile-web-app-capable" content=" ...

  3. idea创建spring boot+mybatis(oracle)+themeleaf项目

    1.新建项目 选择idea已经有的spring initializr next,然后填写项目命名,包名 然后next,选择所需要的依赖 然后一路next,finish,项目新建成功,然后可以删除下面的 ...

  4. 2018.12.08 codeforces 939E. Maximize!(二分答案)

    传送门 二分答案好题. 题意简述:要求支持动态在一个数列队尾加入一个新的数(保证数列单增),查询所有子数列的 最大值减平均值 的最大值. 然而网上一堆高人是用三分做的. 我们先考虑当前的答案有可能由什 ...

  5. Verilog中的阻塞与非阻塞

    这篇文档值得阅读 按说阻塞与非阻塞是Verilog中最基本的东西,也是老生常谈.但是最近看到很多程序里用到阻塞语句竟然不是很明白,说到底是从来没有自己仔细分析过.当然一般情况程序中也是推荐用非阻塞的. ...

  6. 07-css的继承性和层叠性

    css有两大特性:继承性和层叠性 继承性 面向对象语言都会存在继承的概念,在面向对象语言中,继承的特点:继承了父类的属性和方法.那么我们现在主要研究css,css就是在设置属性的.不会牵扯到方法的层面 ...

  7. SSH 等效性问题 总提示输入密码问题

    家目录权限问题 .chmod 700 /home/.. 得到的教训就是没事儿不要乱修改家目录权限,一时方便,可能在别的地方载跟头 ~~ 浪费好许时间 哎

  8. 20170905工作日记--listview优化大全

    1. 适配器设计模式 实例描述:我们国家的电器使用普通的扁平两项或三项插头,而去外国的话,使用的标准就不一样了,比如德国,使用的是两项圆头的插头,那么我们使用的手机充电器插头无法插到德国的插排中去,那 ...

  9. window+R

    好记性不如烂笔头, window+R:打开运行 等同于:所有程序-->附件-->运行

  10. java基础-day29

    第06天 MySQL数据库 今日内容介绍 u MySQL单表查询 u SQL约束 u 多表操作 第1章   MySQL单表查询 1.1  SQL单表查询--排序 1.1.1 排序格式 通过order ...