Swift compile error, subclassing NSValue, using super.init(nonretainedObject:)

This code

class ID<T: AnyObject> : NSValue {
    init(baseObject: T) {
        super.init(nonretainedObject: baseObject)
    }
}

gives this compiler error:

  • Swift protocol property in protocol - Candidate has non-matching type
  • How can I replace my .xib file with pure Swift 3?
  • In Swift, what's the cleanest way to get the last two items in an Array?
  • In my viewDidAppear, how do I know when it's being unwound by a child?
  • How can you get information such as, users window for example using the NSTask class in Swift, for OSX apps?
  • New @convention(c) in Swift 2: How can I use it?
  • error: must call a designated initializer of the superclass 'NSValue'
        super.init(nonretainedObject: baseObject)
        ^
    

    How do I get rid of this?

    Things I thought of

    I thought the error might be because the NSValue initializer has an AnyObject? type (Note well: postfix ?). I tried various flavors of casting and [?!] postfixing in places, and it fixed nothing.

    Also, presumably NSValue(nonretainedObject:) must call the designated initializer, right?

    Solutions Collect From Internet About “Swift compile error, subclassing NSValue, using super.init(nonretainedObject:)”

    NSValue(nonretainedObject:) isn’t a designated initializer. The only initializer listed in the NSValue reference (and hence the designated initializer) is NSValue(value:CConstVoidPointer, withObjCType type:CString)

    The other constructors are all convenience constructors derived from class helper methods.

    You might try:

    init(baseObject: T) {
        super.init(bytes:&baseObject, withObjCType:"^v")
    }
    

    “^v” is the type string returned by an NSValue created with valueWithNonRetained….

    Unfortunately, I’m not coming up with an appropriate way to pass baseObject as a CConstVoidPointer.

    Barring that, the best thing I can come up with is to wrap NSValue instead of subclassing it:

    class ID<T:AnyObject> {
        let wrapped:NSValue
    
        init(baseObject:T) {
            wrapped = NSValue(nonretainedObject:baseObject)
        }
    }
    

    Finally got something to work, but it’s a little bit ugly, basically add a convenience constructor that wraps the nonretainedObject constructor and then use that in your subclass:

    extension NSValue {
        convenience init<T:AnyObject>(unretained:T) {
            self.init(nonretainedObject:unretained)
        }
    }
    
    
    class ID<T>:NSValue {
        convenience init<T:AnyObject>(unretained:T) {
            self.init(unretained:unretained)
        }
    }
    

    Depending on what you’re actually trying to do the category alone might be sufficient?