NSKeyedUnarchiver on Windows doesn't support reference cycles?

This code works on macOS but crashes on Windows with C00000FD (STATUS_STACK_OVERFLOW)

import Foundation

class A: NSObject, NSCoding {
    var b: B?

    func encode(with aCoder: NSCoder) {
        aCoder.encode(b, forKey: "b")
    }

    required init?(coder aDecoder: NSCoder) {
        b = aDecoder.decodeObject(forKey: "b") as? B
        super.init()
    }

    init(b: B?) {
        self.b = b
        super.init()
    }
}

class B: NSObject, NSCoding {
    func encode(with aCoder: NSCoder) {
        aCoder.encode(s, forKey: "s")
        aCoder.encode(d, forKey: "d")
    }

    required init?(coder aDecoder: NSCoder) {
        s = aDecoder.decodeObject(forKey: "s") as! String
        d = aDecoder.decodeObject(forKey: "d") as! [String: A]
        super.init()
    }

    override init() {
        super.init()
    }

    var s: String = ""
    var d: [String: A] = [:]
}

let b_in = B()
b_in.d["0"] = A(b: b_in)
b_in.d["1"] = A(b: b_in)
let data = NSKeyedArchiver.archivedData(withRootObject: b_in)
let b_out_any: Any? = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data)
let b_out = b_out_any as? B
print(b_out)

Is this known limitation or should I fill a bug report?

Linux/Windows/Android do not support the Objective-C runtime. The Foundation on Windows/Linux/Android is a cut-down version of MacOS Foundation, including the removal of all AppKit/UIKit/Objective-C support.

I think, reference tracking doesn't have to be tied to ObjC runtime. Swift's initializers could be a problem, though.

Also I forgot to say, what archiving works just fine. Exception is thrown during unarchiving.

I would expect this to be a bug. Anything encoded by Foundation should be unencodable. Filing a SR for this seems like a good idea (please do include the snippet in the SR as well).

CC: @millenomi

Bug report: https://bugs.swift.org/browse/SR-14504

1 Like
Terms of Service

Privacy Policy

Cookie Policy