append操作为例

  public mutating func append(_ other: String) {
if self.isEmpty && !_guts.hasNativeStorage {
self = other
return
}
self._guts.append(other._guts)
}

_StringGuts 做了实际的工作

下面是实际进行append的地方

  internal mutating func append(_ slicedOther: _StringGutsSlice) {
defer { self._invariantCheck() } if self.isSmall && slicedOther._guts.isSmall {
// TODO: In-register slicing
let smolSelf = self.asSmall
if let smol = slicedOther.withFastUTF8({ otherUTF8 in
return _SmallString(smolSelf, appending: _SmallString(otherUTF8)!)
}) {
self = _StringGuts(smol)
return
}
}
// 进行 copy-on-write 操作
prepareForAppendInPlace(otherUTF8Count: slicedOther.utf8Count) if slicedOther.isFastUTF8 {
let otherIsASCII = slicedOther.isASCII
slicedOther.withFastUTF8 { otherUTF8 in
self.appendInPlace(otherUTF8, isASCII: otherIsASCII)
}
return
} _foreignAppendInPlace(slicedOther)
}

首先判断是否可以安装小字符串处理,然后是重头戏。
我们以实际存储的是native string为例分析。

分配内存操作

  private mutating func prepareForAppendInPlace(
otherUTF8Count otherCount: Int
) {
defer {
_internalInvariant(self.uniqueNativeUnusedCapacity != nil,
"growth should produce uniqueness")
_internalInvariant(self.uniqueNativeUnusedCapacity! >= otherCount,
"growth should produce enough capacity")
} // See if we can accomodate without growing or copying. If we have
// sufficient capacity, we do not need to grow, and we can skip the copy if
// unique. Otherwise, growth is required.
let sufficientCapacity: Bool
if let unused = self.nativeUnusedCapacity, unused >= otherCount {
sufficientCapacity = true
} else {
sufficientCapacity = false
}
//naivestorage的字符串,一定不是UniqueNative的
if self.isUniqueNative && sufficientCapacity {
return
} let totalCount = self.utf8Count + otherCount // Non-unique storage: just make a copy of the appropriate size, otherwise
// grow like an array.
let growthTarget: Int
if sufficientCapacity {
growthTarget = totalCount
} else {
growthTarget = Swift.max(
totalCount, _growArrayCapacity(nativeCapacity ?? 0))
}
//最后会走到这里来
self.grow(growthTarget)
}

一定会调用grow函数。

  internal mutating func grow(_ n: Int) {
defer { self._invariantCheck() } _internalInvariant(
self.uniqueNativeCapacity == nil || self.uniqueNativeCapacity! < n) let growthTarget = Swift.max(n, (self.uniqueNativeCapacity ?? 0) * 2) if _fastPath(isFastUTF8) {
let isASCII = self.isASCII
let storage = self.withFastUTF8 {
// 分配了内存
__StringStorage.create(
initializingFrom: $0, capacity: growthTarget, isASCII: isASCII)
} self = _StringGuts(storage)
return
} _foreignGrow(growthTarget)
}

grow函数里,分配了内存

在分配好的内存里进行内存copy

  internal mutating func appendInPlace(
_ other: UnsafeBufferPointer<UInt8>, isASCII: Bool
) {
self._object.nativeStorage.appendInPlace(other, isASCII: isASCII) // We re-initialize from the modified storage to pick up new count, flags,
// etc.
self = _StringGuts(self._object.nativeStorage)
}
  @_effects(releasenone)
internal func appendInPlace(
_ other: UnsafeBufferPointer<UInt8>, isASCII: Bool
) {
_internalInvariant(self.capacity >= other.count)
let srcAddr = other.baseAddress._unsafelyUnwrappedUnchecked
let srcCount = other.count
self.mutableEnd.initialize(from: srcAddr, count: srcCount)
_postAppendAdjust(appendedCount: srcCount, appendedIsASCII: isASCII)
}

最新文章

  1. 序列化笔记之一:Google的Protocol Buffer格式分析
  2. python基础2(数据类型、数据运算、for循环、while循环、列表)
  3. UI第一节—— UILable
  4. windows tomcat配置大全
  5. Window 点击“X”关闭之后无法show
  6. openstack中iptables的使用
  7. if…else…if…else…
  8. 高仿114la网址导航源码完整最新版
  9. The Swift Programming Language 中国版
  10. 1.自定义控制器切换&lt;一&gt;
  11. 有标号DAG计数 [容斥原理 子集反演 组合数学 fft]
  12. Vue.js02:数据绑定v-model用法
  13. [Swift]LeetCode245.最短单词距离 III $ Shortest Word Distance III
  14. 安装mingw编译器
  15. Spring Boot不同版本整合Redis的配置
  16. pandas DataFrame apply()函数(1)
  17. shell+curl监控网站页面(域名访问状态),并利用sendemail发送邮件
  18. InputMethodManagerService处理输入法——监听APK变动
  19. 1083. List Grades (25)-简单的排序
  20. Zookeeper笔记之基于zk的分布式配置中心

热门文章

  1. centos_x64 6.4 安装jdk1.7
  2. vs2010点调试,显示系统找不到指定的文件
  3. 使用Volley上传文件
  4. idea 优化
  5. POJ3026 Borg Maze 2017-04-21 16:02 50人阅读 评论(0) 收藏
  6. PriorityQueue源码分析
  7. shell 脚本,将/etc/目录下所有的软链接文件输出
  8. Spring注解使用和与配置文件的关系
  9. ASP.NET WEB API 返回JSON 出现2个双引号问题
  10. Jersey Client Post Bean参数