[swift-corelibs-dev] NSCoding methods

Luke Howard lukeh at padl.com
Mon Dec 28 17:51:52 CST 2015


Yeah, that’s what I implemented (although I forgot the synchronized bit, ahem). I backed it out though after your earlier email. I’ll try your patch…

> On 29 Dec 2015, at 10:46 AM, Philippe Hausler <phausler at apple.com> wrote:
> 
>> 
>> 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) {

--
www.lukehoward.com
soundcloud.com/lukehoward



More information about the swift-corelibs-dev mailing list