经验首页 前端设计 程序设计 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

@inlinable
public func map<T>(
_ transform: (Element) throws -> T
) rethrows -> [T] {

  let initialCapacity = underestimatedCount
  var result = ContiguousArray<T>()
  result.reserveCapacity(initialCapacity)

  var iterator = self.makeIterator()

  // Add elements up to the initial capacity without checking for regrowth.
  for _ in 0..<initialCapacity {
    result.append(try transform(iterator.next()!))
  }
  
  // Add remaining elements, if any.
  while let element = iterator.next() {
    // 如果element是数组,会把整个数组作为元素加到新数组中
    result.append(try transform(element))
  }
  
  return Array(result)
}

flatMap

@inlinable
public func flatMap<SegmentOfResult: Sequence>(
_ transform: (Element) throws -> SegmentOfResult
) rethrows -> [SegmentOfResult.Element] {

  var result: [SegmentOfResult.Element] = []
  for element in self {
    // 将数组元素添加到新数组中
    result.append(contentsOf: try transform(element))
  } 
  
  return result
}

filter

@inlinable
public __consuming func filter(
_ isIncluded: (Element) throws -> Bool
) rethrows -> [Element] {
  return try _filter(isIncluded)
}

@_transparent
public func _filter(
_ isIncluded: (Element) throws -> Bool
) rethrows -> [Element] {

  var result = ContiguousArray<Element>()

  var iterator = self.makeIterator()

  while let element = iterator.next() {
    if try isIncluded(element) {
      result.append(element)
    }
  }

  return Array(result)
}

compactMap

@inlinable // protocol-only
public func compactMap<ElementOfResult>(
_ transform: (Element) throws -> ElementOfResult?
) rethrows -> [ElementOfResult] {
  return try _compactMap(transform)
}

@inlinable // protocol-only
@inline(__always)
public func _compactMap<ElementOfResult>(
_ transform: (Element) throws -> ElementOfResult?
) rethrows -> [ElementOfResult] {

  var result: [ElementOfResult] = []
  
  for element in self {
    // 会进行解包,只有不为空才会被加到数组中
    if let newElement = try transform(element) {
      result.append(newElement)
    }
  }
  
  return result
}

reduce

@inlinable
public func reduce<Result>(
_ initialResult: Result,
_ nextPartialResult:
(_ partialResult: Result, Element) throws -> Result
) rethrows -> Result {

  // 上一次的结果
  var accumulator = initialResult
    
  for element in self {
    accumulator = try nextPartialResult(accumulator, element)
  }
  
  return accumulator
}

Substring相关

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

初始化

@frozen
public struct Substring: ConcurrentValue {
  @usableFromInline
  internal var _slice: Slice<String>

  @inlinable
  internal init(_ slice: Slice<String>) {
    let _guts = slice.base._guts
    let start = _guts.scalarAlign(slice.startIndex)
    let end = _guts.scalarAlign(slice.endIndex)
    
    // 保存传进来的字符串的内容和位置
    self._slice = Slice(
      base: slice.base,
      bounds: Range(_uncheckedBounds: (start, end))) 
    _invariantCheck()
  }

  @inline(__always)
  internal init(_ slice: _StringGutsSlice) {
    self.init(String(slice._guts)[slice.range])
  }

  /// Creates an empty substring.
  @inlinable @inline(__always)
  public init() {
    self.init(Slice())
  }
}

extension Substring {
  /// Returns the underlying string from which this Substring was derived.
  @_alwaysEmitIntoClient
  
  // _slice.base就是初始化传进来的字符串
  public var base: String { return _slice.base }

  @inlinable @inline(__always)
  internal var _wholeGuts: _StringGuts { return base._guts }

  @inlinable @inline(__always)

  // 从这里也能看出和传进来的String共有的是同一块区域,在这块区域进行偏移获取Substring的内容
  internal var _offsetRange: Range<Int> {
    return Range(
      _uncheckedBounds: (startIndex._encodedOffset, endIndex._encodedOffset))
  }

  #if !INTERNAL_CHECKS_ENABLED
  @inlinable @inline(__always) internal func _invariantCheck() {}
  #else
  @usableFromInline @inline(never) @_effects(releasenone)
  internal func _invariantCheck() {
    // Indices are always scalar aligned
    _internalInvariant(
      _slice.startIndex == base._guts.scalarAlign(_slice.startIndex) &&
      _slice.endIndex == base._guts.scalarAlign(_slice.endIndex))

    self.base._invariantCheck()
  }
  #endif // INTERNAL_CHECKS_ENABLED
}

append

extension Substring: RangeReplaceableCollection {
  @_specialize(where S == String)
  @_specialize(where S == Substring)
  @_specialize(where S == Array<Character>)
  public init<S: Sequence>(_ elements: S)
  where S.Element == Character {
    if let str = elements as? String {
      self.init(str)
      return
    }
    if let subStr = elements as? Substring {
      self = subStr
      return
    }
    self.init(String(elements))
  }

  // Substring的拼接
  @inlinable // specialize
  public mutating func append<S: Sequence>(contentsOf elements: S)
  where S.Element == Character {

		// 拼接时会创建一个新的字符串
    var string = String(self)
    self = Substring() // Keep unique storage if possible
    string.append(contentsOf: elements)
    self = Substring(string)
  }
}

lowercased、uppercased

extension Substring {
  public func lowercased() -> String {
    return String(self).lowercased()
  }

  public func uppercased() -> String {
    return String(self).uppercased()
  }

  public func filter(
    _ isIncluded: (Element) throws -> Bool
  ) rethrows -> String {
    return try String(self.lazy.filter(isIncluded))
  }
}

Optional相关

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

map

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

flatMap

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

==

==两边都为可选项

@inlinable
public static func ==(lhs: Wrapped?, rhs: Wrapped?) -> Bool {
  switch (lhs, rhs) {
    case let (l?, r?):
      return l == r
    case (nil, nil):
      return true
    default:
      return false
  }
}

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

@_transparent
public static func ==(lhs: Wrapped?, rhs: _OptionalNilComparisonType) -> Bool {
  switch lhs {
    case .some:
      return false
    case .none:
      return true
  }
}

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

@_transparent
public static func ==(lhs: _OptionalNilComparisonType, rhs: Wrapped?) -> Bool {
  switch rhs {
    case .some:
      return false
    case .none:
      return true
  }
}

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

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

??

@_transparent
public func ?? <T>(optional: T?, defaultValue: @autoclosure () throws -> T)
    rethrows -> T {
  switch optional {
  case .some(let value):
    return value
  case .none:
    return try defaultValue()
  }
}
@_transparent
public func ?? <T>(optional: T?, defaultValue: @autoclosure () throws -> T?)
    rethrows -> T? {
  switch optional {
  case .some(let value):
    return value
  case .none:
    return try defaultValue()
  }
}

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信息

struct ClassLayout: ModelLayout {
    let kind: UnsafeRawPointer
    
    /// 指向父类类型的指针
    let superclass: Any.Type
    
    /// 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
    /// 缓存数据用于某些动态查找;它属于运行时,通常需要与Objective-C的使用进行互操作
    let runtimeReserved0: UInt
    let runtimeReserved1: UInt
    
    /// 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
    let rodata: UInt
    
    /// Swift-specific class flags
    /// 类标志
    let flags: UInt32
    
    /// The address point of instances of this type
    /// 实例的地址值
    let instanceAddressPoint: UInt32

    /// The required size of instances of this type. 'InstanceAddressPoint' bytes go before the address point; 'InstanceSize - InstanceAddressPoint' bytes go after it
    /// 实例大小
    let instanceSize: UInt32

    /// The alignment mask of the address point of instances of this type
    /// 实例对齐掩码
    let instanceAlignMask: UInt16

    /// Reserved for runtime use
    /// 运行时保留字段
    let reserved: UInt16

    /// The total size of the class object, including prefix and suffix extents
    /// 类对象的大小
    let classSize: UInt32

    /// The offset of the address point within the class object
    /// 类对象地址
    let classAddressPoint: UInt32

    // Description is by far the most likely field for a client to try to access directly, so we force access to go through accessors
    /// 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
    var description: UnsafeMutablePointer<ClassDescriptor>
    
    /// 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
    let iVarDestroyer: UnsafeRawPointer
    
    var genericTypeOffset: Int {
        let descriptor = description.pointee
        // don't have resilient superclass
        if (0x4000 & flags) == 0 {
            return (flags & 0x800) == 0
            ? Int(descriptor.metadataPositiveSizeInWords - descriptor.numImmediateMembers)
            : -Int(descriptor.metadataNegativeSizeInWords)
        }
        return GenenicTypeOffset.wrong
    }
}

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

 友情链接: NPS