2

这段代码

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

给出这个编译器错误:

error: must call a designated initializer of the superclass 'NSValue'
    super.init(nonretainedObject: baseObject)
    ^

我该如何摆脱这个?

我想到的事情

我认为错误可能是因为NSValue初始化程序有一个AnyObject?类型(注意:后缀 ?)。我在一些地方尝试了各种类型的铸造和[?!]后缀,但它什么也没解决。

另外,大概NSValue(nonretainedObject:)必须调用指定的初始化程序,对吧?

4

1 回答 1

2

NSValue(nonretainedObject:)不是指定的初始化程序。NSValue 引用中列出的唯一初始化程序(以及因此指定的初始化程序)是NSValue(value:CConstVoidPointer, withObjCType type:CString)

其他构造函数都是从类助手方法派生的便利构造函数。

你可以试试:

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

"^v" 是使用 valueWithNonRetained... 创建的 NSValue 返回的类型字符串。

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?

于 2014-06-27T15:59:05.283 回答