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. 制作centos sshd 镜像

    [root@b5926410fe60 /]# yum install passwd openssl openssh-server -y 启动sshd: # /usr/sbin/sshd -D 这时报以 ...

  2. 2019.01.21 bzoj1758: [Wc2010]重建计划(01分数规划+长链剖分+线段树)

    传送门 长链剖分好题. 题意简述:给一棵树,问边数在[L,R][L,R][L,R]之间的路径权值和与边数之比的最大值. 思路: 用脚指头想都知道要01分数规划. 考虑怎么checkcheckcheck ...

  3. hdu-1043(八数码+bfs打表+康托展开)

    参考文章:https://www.cnblogs.com/Inkblots/p/4846948.html 康托展开:https://blog.csdn.net/wbin233/article/deta ...

  4. 关于xftp上传文件状态错误的解决

    新建一个文件夹,/usr/local/wwj 更改wwj权限 chmod 777 wwj 然后就可以上传了 如果还不行,就关闭防火墙

  5. Nginx使用(配置开机启动)

    环境: 系统:CentOS 6.5 Final 安装目录:/usr/local/nginx Nginx开机自启: ①编写shell实现控制 vi /etc/init.d/nginx 添加内容: #!/ ...

  6. spring之jdbcTemplate

    spring的另一个功能模块data access对于数据库的支持 spring data access第一个helloword案例: 使用java程序实现访问配置 1.导包 2.测试案例 @Test ...

  7. 待了解概念_GraphicsView

    Linux 的 KDE 是建立在 Graphics view基础上的. 新版本KDE 有向QML前移的趋势. Graphics View 使用了BSP 树的结构. Graphics View 是一个基 ...

  8. Hdu1205 吃糖果 2017-06-29 14:26 24人阅读 评论(0) 收藏

    吃糖果 Problem Description HOHO,终于从Speakless手上赢走了所有的糖果,是Gardon吃糖果时有个特殊的癖好,就是不喜欢将一样的糖果放在一起吃,喜欢先吃一种,下一次吃另 ...

  9. hdu 1698 Just a Hook 【线段树+lazy】

    题目 写了一天的线段树,这道题主要说明一下sum是赋值的,不是累加的,并且在push_down的时候lazy也是赋值的.因可能对懒标记的理解还不是很透彻吧. #include <iostream ...

  10. spark checkpoint详解

    checkpoint在spark中主要有两块应用:一块是在spark core中对RDD做checkpoint,可以切断做checkpoint RDD的依赖关系,将RDD数据保存到可靠存储(如HDFS ...