[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