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

1,837 views

Published on

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

Published in: Software
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,837
On SlideShare
0
From Embeds
0
Number of Embeds
1,312
Actions
Shares
0
Downloads
2
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

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 }

×