[swift-corelibs-dev] NSCoding methods

Philippe Hausler phausler at apple.com
Mon Dec 28 17:46:46 CST 2015


> On Dec 28, 2015, at 3:10 PM, Luke Howard <lukeh at padl.com> wrote:
> 
> 
>> On 29 Dec 2015, at 3:01 AM, Philippe Hausler <phausler at apple.com> wrote:
>> 
>> Not certain what you mean there; each NSValue is just a identity of a key in a dictionary to a NSConcreteValue that the methods forward to? That would mean that each method call would be a dictionary lookup… that does not sound scalable from a performance standpoint.
> 
> Although didn’t NSObject do something similar for managing the retain count when it didn’t fit inline? I’m too lazy to go look it up...
> 
> — Luke

Yea the objc runtime has side tables for things like that; I guess I would have to see a proposed implementation and play with it to see what the performance hit would be like.

So you were thinking something like (note this is just something I drafted in a few minutes so it is a bit rough):

diff --git a/Foundation/NSDecimalNumber.swift b/Foundation/NSDecimalNumber.swift
index 927be14..2e6791f 100644
--- a/Foundation/NSDecimalNumber.swift
+++ b/Foundation/NSDecimalNumber.swift
@@ -96,7 +96,7 @@ public class NSDecimalNumber : NSNumber {
     //   ignore exactnessException
     //   raise on overflow, underflow and divide by zero.
     
-    public var objCType: UnsafePointer<Int8> { NSUnimplemented() }
+    public override var objCType: UnsafePointer<Int8> { NSUnimplemented() }
     // return 'd' for double
     
     public override var doubleValue: Double { NSUnimplemented() }
diff --git a/Foundation/NSValue.swift b/Foundation/NSValue.swift
index eefb3b9..6f495a0 100644
--- a/Foundation/NSValue.swift
+++ b/Foundation/NSValue.swift
@@ -8,10 +8,68 @@
 //
 
 
+internal class NSConcreteValue : NSValue {
+    internal var _value: UnsafeMutablePointer<Void> = nil
+    internal var _size: Int = 0
+    internal var _objCType: UnsafePointer<Int8> = nil
+    
+    internal override init() {
+        super.init()
+    }
+
+    required init?(coder aDecoder: NSCoder) {
+        NSUnimplemented()
+    }
+    
+    override func getValue(value: UnsafeMutablePointer<Void>) {
+        value.assignFrom(_value, count: _size)
+    }
+    
+    override var objCType: UnsafePointer<Int8> {
+        return _objCType
+    }
+}
+
+private var _NSValueSideTable = [ObjectIdentifier : NSConcreteValue]()
+private var _NSValueSideTableLock = NSLock()
+
 public class NSValue : NSObject, NSCopying, NSSecureCoding, NSCoding {
     
     internal override init() {
-        
+        super.init()
+        if self.dynamicType == NSValue.self {
+            _NSValueSideTableLock.synchronized {
+                _NSValueSideTable[ObjectIdentifier(self)] = NSConcreteValue()
+            }
+        }
+    }
+    
+    deinit {
+        if self.dynamicType == NSValue.self {
+            _NSValueSideTableLock.synchronized {
+                _NSValueSideTable[ObjectIdentifier(self)] = nil
+            }
+        }
+    }
+    
+    public func getValue(value: UnsafeMutablePointer<Void>) {
+        if self.dynamicType == NSValue.self {
+            _NSValueSideTableLock.synchronized {
+                _NSValueSideTable[ObjectIdentifier(self)]!.getValue(value)
+            }
+        } else {
+            NSRequiresConcreteImplementation()
+        }
+    }
+    
+    public var objCType: UnsafePointer<Int8> {
+        if self.dynamicType == NSValue.self {
+            return _NSValueSideTableLock.synchronized {
+                return _NSValueSideTable[ObjectIdentifier(self)]!.objCType
+            }
+        } else {
+            NSRequiresConcreteImplementation()
+        }
     }
     
     public required init?(coder aDecoder: NSCoder) {



More information about the swift-corelibs-dev mailing list