经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » iOS » 查看文章
Swift 进阶(十七)源码分析
来源:cnblogs  作者:FunkyRay  时间:2021/4/6 10:05:49  对本文有异议

我们通过分析Swift标准库源码来更近一步了解Swift的语法

Array相关

map、filter的源码路径:/swift-main/stdlib/public/core/Sequence.swift

flatMap、compactMap、reduce的源码路径:/swift-main/stdlib/public/core/SequenceAlgorithms.swift

map

  1. @inlinable
  2. public func map<T>(
  3. _ transform: (Element) throws -> T
  4. ) rethrows -> [T] {
  5. let initialCapacity = underestimatedCount
  6. var result = ContiguousArray<T>()
  7. result.reserveCapacity(initialCapacity)
  8. var iterator = self.makeIterator()
  9. // Add elements up to the initial capacity without checking for regrowth.
  10. for _ in 0..<initialCapacity {
  11. result.append(try transform(iterator.next()!))
  12. }
  13. // Add remaining elements, if any.
  14. while let element = iterator.next() {
  15. // 如果element是数组,会把整个数组作为元素加到新数组中
  16. result.append(try transform(element))
  17. }
  18. return Array(result)
  19. }

flatMap

  1. @inlinable
  2. public func flatMap<SegmentOfResult: Sequence>(
  3. _ transform: (Element) throws -> SegmentOfResult
  4. ) rethrows -> [SegmentOfResult.Element] {
  5. var result: [SegmentOfResult.Element] = []
  6. for element in self {
  7. // 将数组元素添加到新数组中
  8. result.append(contentsOf: try transform(element))
  9. }
  10. return result
  11. }

filter

  1. @inlinable
  2. public __consuming func filter(
  3. _ isIncluded: (Element) throws -> Bool
  4. ) rethrows -> [Element] {
  5. return try _filter(isIncluded)
  6. }
  7. @_transparent
  8. public func _filter(
  9. _ isIncluded: (Element) throws -> Bool
  10. ) rethrows -> [Element] {
  11. var result = ContiguousArray<Element>()
  12. var iterator = self.makeIterator()
  13. while let element = iterator.next() {
  14. if try isIncluded(element) {
  15. result.append(element)
  16. }
  17. }
  18. return Array(result)
  19. }

compactMap

  1. @inlinable // protocol-only
  2. public func compactMap<ElementOfResult>(
  3. _ transform: (Element) throws -> ElementOfResult?
  4. ) rethrows -> [ElementOfResult] {
  5. return try _compactMap(transform)
  6. }
  7. @inlinable // protocol-only
  8. @inline(__always)
  9. public func _compactMap<ElementOfResult>(
  10. _ transform: (Element) throws -> ElementOfResult?
  11. ) rethrows -> [ElementOfResult] {
  12. var result: [ElementOfResult] = []
  13. for element in self {
  14. // 会进行解包,只有不为空才会被加到数组中
  15. if let newElement = try transform(element) {
  16. result.append(newElement)
  17. }
  18. }
  19. return result
  20. }

reduce

  1. @inlinable
  2. public func reduce<Result>(
  3. _ initialResult: Result,
  4. _ nextPartialResult:
  5. (_ partialResult: Result, Element) throws -> Result
  6. ) rethrows -> Result {
  7. // 上一次的结果
  8. var accumulator = initialResult
  9. for element in self {
  10. accumulator = try nextPartialResult(accumulator, element)
  11. }
  12. return accumulator
  13. }

Substring相关

Substring的源码路径:/swift-main/stdlib/public/core/Substring.swift

初始化

  1. @frozen
  2. public struct Substring: ConcurrentValue {
  3. @usableFromInline
  4. internal var _slice: Slice<String>
  5. @inlinable
  6. internal init(_ slice: Slice<String>) {
  7. let _guts = slice.base._guts
  8. let start = _guts.scalarAlign(slice.startIndex)
  9. let end = _guts.scalarAlign(slice.endIndex)
  10. // 保存传进来的字符串的内容和位置
  11. self._slice = Slice(
  12. base: slice.base,
  13. bounds: Range(_uncheckedBounds: (start, end)))
  14. _invariantCheck()
  15. }
  16. @inline(__always)
  17. internal init(_ slice: _StringGutsSlice) {
  18. self.init(String(slice._guts)[slice.range])
  19. }
  20. /// Creates an empty substring.
  21. @inlinable @inline(__always)
  22. public init() {
  23. self.init(Slice())
  24. }
  25. }
  26. extension Substring {
  27. /// Returns the underlying string from which this Substring was derived.
  28. @_alwaysEmitIntoClient
  29. // _slice.base就是初始化传进来的字符串
  30. public var base: String { return _slice.base }
  31. @inlinable @inline(__always)
  32. internal var _wholeGuts: _StringGuts { return base._guts }
  33. @inlinable @inline(__always)
  34. // 从这里也能看出和传进来的String共有的是同一块区域,在这块区域进行偏移获取Substring的内容
  35. internal var _offsetRange: Range<Int> {
  36. return Range(
  37. _uncheckedBounds: (startIndex._encodedOffset, endIndex._encodedOffset))
  38. }
  39. #if !INTERNAL_CHECKS_ENABLED
  40. @inlinable @inline(__always) internal func _invariantCheck() {}
  41. #else
  42. @usableFromInline @inline(never) @_effects(releasenone)
  43. internal func _invariantCheck() {
  44. // Indices are always scalar aligned
  45. _internalInvariant(
  46. _slice.startIndex == base._guts.scalarAlign(_slice.startIndex) &&
  47. _slice.endIndex == base._guts.scalarAlign(_slice.endIndex))
  48. self.base._invariantCheck()
  49. }
  50. #endif // INTERNAL_CHECKS_ENABLED
  51. }

append

  1. extension Substring: RangeReplaceableCollection {
  2. @_specialize(where S == String)
  3. @_specialize(where S == Substring)
  4. @_specialize(where S == Array<Character>)
  5. public init<S: Sequence>(_ elements: S)
  6. where S.Element == Character {
  7. if let str = elements as? String {
  8. self.init(str)
  9. return
  10. }
  11. if let subStr = elements as? Substring {
  12. self = subStr
  13. return
  14. }
  15. self.init(String(elements))
  16. }
  17. // Substring的拼接
  18. @inlinable // specialize
  19. public mutating func append<S: Sequence>(contentsOf elements: S)
  20. where S.Element == Character {
  21. // 拼接时会创建一个新的字符串
  22. var string = String(self)
  23. self = Substring() // Keep unique storage if possible
  24. string.append(contentsOf: elements)
  25. self = Substring(string)
  26. }
  27. }

lowercased、uppercased

  1. extension Substring {
  2. public func lowercased() -> String {
  3. return String(self).lowercased()
  4. }
  5. public func uppercased() -> String {
  6. return String(self).uppercased()
  7. }
  8. public func filter(
  9. _ isIncluded: (Element) throws -> Bool
  10. ) rethrows -> String {
  11. return try String(self.lazy.filter(isIncluded))
  12. }
  13. }

Optional相关

Optional的源码路径:/swift-main/stdlib/public/core/Optional.swift

map

  1. @inlinable
  2. public func map<U>(
  3. _ transform: (Wrapped) throws -> U
  4. ) rethrows -> U? {
  5. switch self {
  6. case .some(let y): // 先解包进行处理
  7. return .some(try transform(y)) // 然后再包装一层可选类型返回出去
  8. case .none:
  9. return .none
  10. }
  11. }

flatMap

  1. @inlinable
  2. public func flatMap<U>(
  3. _ transform: (Wrapped) throws -> U?
  4. ) rethrows -> U? {
  5. switch self {
  6. case .some(let y): // 先进行解包
  7. return try transform(y) // 将解包后的处理完直接给出去
  8. case .none:
  9. return .none
  10. }
  11. }

==

==两边都为可选项

  1. @inlinable
  2. public static func ==(lhs: Wrapped?, rhs: Wrapped?) -> Bool {
  3. switch (lhs, rhs) {
  4. case let (l?, r?):
  5. return l == r
  6. case (nil, nil):
  7. return true
  8. default:
  9. return false
  10. }
  11. }

==左边为可选项,右边为nil

  1. @_transparent
  2. public static func ==(lhs: Wrapped?, rhs: _OptionalNilComparisonType) -> Bool {
  3. switch lhs {
  4. case .some:
  5. return false
  6. case .none:
  7. return true
  8. }
  9. }

==左边为nil,右边为可选项

  1. @_transparent
  2. public static func ==(lhs: _OptionalNilComparisonType, rhs: Wrapped?) -> Bool {
  3. switch rhs {
  4. case .some:
  5. return false
  6. case .none:
  7. return true
  8. }
  9. }

_OptionalNilComparisonType是一个遵守ExpressibleByNilLiteral协议的结构体,可以用nil来进行初始化

  1. // 遵守ExpressibleByNilLiteral协议的结构体,可以用nil来进行初始化
  2. @frozen
  3. public struct _OptionalNilComparisonType: ExpressibleByNilLiteral {
  4. /// Create an instance initialized with `nil`.
  5. @_transparent
  6. public init(nilLiteral: ()) {
  7. }
  8. }

??

  1. @_transparent
  2. public func ?? <T>(optional: T?, defaultValue: @autoclosure () throws -> T)
  3. rethrows -> T {
  4. switch optional {
  5. case .some(let value):
  6. return value
  7. case .none:
  8. return try defaultValue()
  9. }
  10. }
  1. @_transparent
  2. public func ?? <T>(optional: T?, defaultValue: @autoclosure () throws -> T?)
  3. rethrows -> T? {
  4. switch optional {
  5. case .some(let value):
  6. return value
  7. case .none:
  8. return try defaultValue()
  9. }
  10. }

Metadata相关

源码路径:

/swift-main/include/swift/ABI/Metadata.h
/swift-main/include/swift/ABI/MetadataKind.def
/swift-main/include/swift/ABI/MetadataValues.h
/swift-main/include/swift/Reflection/Records.h

文档路径:

/swift-main/docs/ABI/TypeMetadata.rst

Swift中很多类型都有自己的metadata

-w1020

Class Metadata

我们可以从第三方库KaKaJSON中的ClassType,以及对应Metadata的相关文档来分析Class Metadata信息

  1. struct ClassLayout: ModelLayout {
  2. let kind: UnsafeRawPointer
  3. /// 指向父类类型的指针
  4. let superclass: Any.Type
  5. /// The cache data is used for certain dynamic lookups; it is owned by the runtime and generally needs to interoperate with Objective-C's use
  6. /// 缓存数据用于某些动态查找;它属于运行时,通常需要与Objective-C的使用进行互操作
  7. let runtimeReserved0: UInt
  8. let runtimeReserved1: UInt
  9. /// The data pointer is used for out-of-line metadata and is generally opaque, except that the compiler sets the low bit in order to indicate that this is a Swift metatype and therefore that the type metadata header is present
  10. let rodata: UInt
  11. /// Swift-specific class flags
  12. /// 类标志
  13. let flags: UInt32
  14. /// The address point of instances of this type
  15. /// 实例的地址值
  16. let instanceAddressPoint: UInt32
  17. /// The required size of instances of this type. 'InstanceAddressPoint' bytes go before the address point; 'InstanceSize - InstanceAddressPoint' bytes go after it
  18. /// 实例大小
  19. let instanceSize: UInt32
  20. /// The alignment mask of the address point of instances of this type
  21. /// 实例对齐掩码
  22. let instanceAlignMask: UInt16
  23. /// Reserved for runtime use
  24. /// 运行时保留字段
  25. let reserved: UInt16
  26. /// The total size of the class object, including prefix and suffix extents
  27. /// 类对象的大小
  28. let classSize: UInt32
  29. /// The offset of the address point within the class object
  30. /// 类对象地址
  31. let classAddressPoint: UInt32
  32. // Description is by far the most likely field for a client to try to access directly, so we force access to go through accessors
  33. /// An out-of-line Swift-specific description of the type, or null if this is an artificial subclass. We currently provide no supported mechanism for making a non-artificial subclass dynamically
  34. var description: UnsafeMutablePointer<ClassDescriptor>
  35. /// A function for destroying instance variables, used to clean up after an early return from a constructor. If null, no clean up will be performed and all ivars must be trivial
  36. let iVarDestroyer: UnsafeRawPointer
  37. var genericTypeOffset: Int {
  38. let descriptor = description.pointee
  39. // don't have resilient superclass
  40. if (0x4000 & flags) == 0 {
  41. return (flags & 0x800) == 0
  42. ? Int(descriptor.metadataPositiveSizeInWords - descriptor.numImmediateMembers)
  43. : -Int(descriptor.metadataNegativeSizeInWords)
  44. }
  45. return GenenicTypeOffset.wrong
  46. }
  47. }

原文链接:http://www.cnblogs.com/funkyRay/p/swift-jin-jie-shi-qi-yuan-ma-fen-xi.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号