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?タイプがあるため、エラーが発生した可能性があると思いました(よく注意してください: postfix ?)。さまざまな種類のキャストと[?!]後置をいくつか試しましたが、何も修正されませんでした。

また、おそらく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 によって返される型文字列です。

残念ながら、私はbaseObjectCConstVoidPointer として渡す適切な方法を思いつきません。

それを除けば、私が思いつく最善の方法は、サブクラス化する代わりに NSValue をラップすることです。

class ID<T:AnyObject> {
    let wrapped:NSValue

    init(baseObject:T) {
        wrapped = NSValue(nonretainedObject:baseObject)
    }
}

最終的に何かが機能するようになりましたが、少し醜いです。基本的には、nonretainedObject コンストラクターをラップする便利なコンストラクターを追加し、それをサブクラスで使用します。

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)
    }
}

実際に何をしようとしているかによっては、カテゴリだけで十分でしょうか?

于 2014-06-27T15:59:05.283 に答える