Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

NS Prefix 外伝 … Copy-On-Write #関モバ

3,086 views

Published on

Swift 3 の変化のひとつに Foundation での NS プレフィックス削除があります。その中でも、とりわけ "新しい値型" の新設に伴って、値型とクラス型をブリッジする選択が取られた型の、そのパフォーマンスの最適化に注目してみました。

Published in: Software
  • Be the first to comment

NS Prefix 外伝 … Copy-On-Write #関モバ

  1. 1. 

  2. 2. • NSString, String • NSData, Data • NSArray, Array<Element>
  3. 3. // 要所だけ抜粋 protocol ReferenceConvertible : _ObjectiveCBridgeable { // 参照型は Objective-C 互換で、コピー可能 associatedtype ReferenceType : NSObject, NSCopying }
  4. 4. 
 

  5. 5. public struct Data : ReferenceConvertible, _MutablePairBoxing { // NSData とのブリッジ public typealias ReferenceType = NSData // 参照をラップ (Boxing) する internal var _wrapped : _SwiftNSData
  6. 6. internal final class _SwiftNSData { // NSData と NSMutableData とを管理するラッパー var __wrapped : _MutableUnmanagedWrapper< NSData, NSMutableData>
  7. 7. internal enum _MutableUnmanagedWrapper< ImmutableType, MutableType> { case Immutable(Unmanaged<ImmutableType>) case Mutable(Unmanaged<MutableType>) }
  8. 8. public init(bytes: UnsafeRawPointer, count: Int) { _wrapped = _SwiftNSData(immutableObject: NSData(bytes: bytes, length: count)) }
  9. 9. public mutating func append(_ other: Data) { // この関数で mutableCopy の必要性を判断・実施 _applyUnmanagedMutation { $0.append(other) } }
  10. 10. public init(capacity: Int) { if let d = NSMutableData(capacity: capacity) { _wrapped = _SwiftNSData(mutableObject: d) } else { fatalError("Unable to allocate data of the requested capacity") } }
  11. 11. public func _bridgeToObjectiveC() -> NSData { // NSData.self は 8 Byte return unsafeBitCast(_wrapped, to: NSData.self) }
  12. 12. public static func _forceBridgeFromObjectiveC( _ input: NSData, result: inout Data?) { result = Data(referencing: input) } public init(referencing reference: NSData) { _wrapped = _SwiftNSData(immutableObject: reference.copy() as AnyObject) }
  13. 13. public struct Date : ReferenceConvertible { // NSDate とのブリッジ public typealias ReferenceType = NSDate // データを TimeInterval (Double) で直接保持 fileprivate var _time : TimeInterval
  14. 14. public init(timeIntervalSinceReferenceDate ti: TimeInterval) { _time = ti }
  15. 15. public mutating func addTimeInterval( _ timeInterval: TimeInterval) { self += timeInterval }
  16. 16. public func _bridgeToObjectiveC() -> NSDate { return NSDate(timeIntervalSinceReferenceDate: _time) }
  17. 17. public static func _conditionallyBridgeFromObjectiveC( _ x: NSDate, result: inout Date?) -> Bool { result = Date(timeIntervalSinceReferenceDate: x.timeIntervalSinceReferenceDate) return true }

×