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. 使用 kbmmw 的ORM开发纯REST数据库访问服务

    运行环境: WIN 10  X64 delphi 10.2.2 kbmmw 5.05.11 Firefox 58.0.2 今天使用最新的kbmmw 版本做一个基于ORM的纯数据库访问的REST 服务器 ...

  2. 网络编程之基于tcp和udp的套接字

    一   udp协议网络编程 DNS:将域名解析成ip地址 SOCK_DGRAM:数据报协议,也是udp协议 udp协议的网络编程的一些用法: recvfrom:接收消息,接收的时一个元组,元组里面的元 ...

  3. PHP获取手机号

    /** * 类名: mobile * 描述: 手机信息类 * 其他: 偶然 编写 */ class mobile{ /** * 函数名称: getPhoneNumber * 函数功能: 取手机号 * ...

  4. 获取POM.XML依赖的JAR包

    pom.xml 文件的依赖在本地仓库中,有些情况我需要根据pom.xml 抓取所有依赖的JAR包. 这个可以通过 ant 完成这个包的抓取. <target name="maven-j ...

  5. vue 开发系列(六) 企业微信整合

    概述 手机端程序可以和企业微信进行整合,我们也可以使用企业微信JSSDK功能,实现一些原生的功能. 整合步骤 在整合之前需要阅读 整合步骤. http://work.weixin.qq.com/api ...

  6. PLSQL Developer对oracle中的数据进行备份恢复

    1.备份数据结构 --进入  工具-->导出用户对象  如图所示 把包括所有者的√去掉,到时候我们就可以随便建一个用户导入数据了,不一定非要scott用户   2.备份数据 工具-->导出 ...

  7. 利用xshell远程连接centos安装oracle11g时在图形界面登录

    1.首先给centos安装桌面环境.( yum groupinstall ‘GNOME Desktop’) 2.安装Xmanager软件 3.打开xshell,新建连接 填好主机和名称后,点击左侧连接 ...

  8. java常用设计模式二:工厂模式

    1.简单工厂模式(静态工厂方法模式) 抽象实例: public interface People { void talk(); } 具体实例: public class Doctor implemen ...

  9. ubuntu设置IP地址、网关的方法

    打开terminal(用Ctrl+Alt+T打开) 1. 输入ifconfig  打印如下: enp1s0    Link encap:Ethernet  HWaddr 6c:4b:90:0b:53: ...

  10. Struts2-result

    所有result-type <result-types> <result-type name="chain" class="com.opensympho ...