apple/swift - stdlib/public/SDK/ObjectiveC コードリーディング(全体)

概要

swift/stdlib/public/SDK/ObjectiveC at master · apple/swift · GitHub

ObjectiveC.swift

ObjCBool

Objective-C BOOL型、64bitのiOSではC / C++ boolのtypedefで、他ではsigned charとしている

Clang ImporterはObjCBool型としてインポートしている

定義

@_fixed_layout
public struct ObjCBool : ExpressibleByBooleanLiteral

ObjCBool型はBoolのリテラルとして振る舞う為にExpressibleByBooleanLiteralプロトコルに準拠している

他の準拠プロトコルとしてはCustomReflectableCustomStringConvertibleがあるが今回は省略する

Selector

定義

@_fixed_layout
public struct Selector : ExpressibleByStringLiteral

Selector型は文字列リテラルとして振る舞う為に、ExpressibleByBooleanLiteralプロトコルに準拠している

上述同様に他の準拠プロトコルとしてはCustomReflectableCustomStringConvertibleなどがあるが今回は省略する

NSZone

@_fixed_layout
public struct NSZone {
  var pointer: OpaquePointer
}

// Note: NSZone becomes Zone in Swift 3.
typealias Zone = NSZone

コメント通りNSZoneはSwift3からZoneとしてaliasが貼られている

OpaquePointerをプロパティとして持っているので、実装を隠す意図でこの定義をしてると想定できる

autoreleasepool

public func autoreleasepool<Result>(
  invoking body: () throws -> Result
) rethrows -> Result {
  let pool = _swift_objc_autoreleasePoolPush()
  defer {
    _swift_objc_autoreleasePoolPop(pool)
  }
  return try body()
}

Objective-C時代の@autoreleasepoolの機能を代替してくれる関数

RCStateTransition.cppからisAutoreleasePoolCallにて呼び出されている

_swift_objc_autoreleasePoolPush_swift_objc_autoreleasePoolPop_swift_のprefixが動的に付与されている模様

参考

Swift3.0時代のautoreleasepoolは素晴らしい | Tomorrow Never Comes.

NSObject

等価性比較 & hash対応

// NSObject implements Equatable's == as -[NSObject isEqual:]
// NSObject implements Hashable's hashValue() as -[NSObject hash]
// FIXME: what about NSObjectProtocol?

extension NSObject : Equatable, Hashable {
  public static func == (lhs: NSObject, rhs: NSObject) -> Bool {
    return lhs.isEqual(rhs)
  }

  /// The hash value.
  ///
  /// **Axiom:** `x == y` implies `x.hashValue == y.hashValue`
  ///
  /// - Note: the hash value is not guaranteed to be stable across
  ///   different invocations of the same program.  Do not persist the
  ///   hash value across program runs.
  @objc
  open var hashValue: Int {
    return hash
  }
}

まずNSObject系統のクラス群はポインタの等価性チェックを行う際に- (BOOL)isEqual:(NSObject *)を使う為、それをSwiftの世界で等価性を比較をするのにEquatableプロトコルに乗っけることで実現している

同じように- (int)hashはNSObject系統でのHashableプロトコルで返すhashValueと意味合いが同じため、Hashableプロトコルとして返すように繋げている

CVarArg

extension NSObject : CVarArg {
  /// Transform `self` into a series of machine words that can be
  /// appropriately interpreted by C varargs
  public var _cVarArgEncoding: [Int] {
    _autorelease(self)
    return _encodeBitsAsWords(self)
  }
}

CVarArgプロトコルに準拠することで機械語の変換を可能にする