[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