正しい nib 名で UIViewController を作成するファブリック メソッドを作成しようとしています (iOS8 のデフォルトの初期化子の問題を修正するため)。それを行うために、拡張機能を追加しました:
extension UIViewController {
class func create() -> Self {
if #available(iOS 9.0, *) {
return self.init()
} else {
let clsName = NSStringFromClass(self).componentsSeparatedByString(".").last!
return self.init(nibName: clsName, bundle: nil)
}
}
}
ただし、コンパイラは error: Cannot convert value of type 'Self.Type' to expected argument type 'AnyClass' (aka 'AnyObject.Type')
in を発行しますNSStringFromClass(self)
。
これを修正するには、別の拡張メソッドを追加して、コードを次のように書き換えます。
extension UIViewController {
private class var nibNameForInitializer:String {
return NSStringFromClass(self).componentsSeparatedByString(".").last!
}
class func create_() -> Self {
if #available(iOS 9.0, *) {
return self.init()
} else {
return self.init(nibName: self.nibNameForInitializer, bundle: nil)
}
}
}
ただし、最初のバリアントの問題を理解したいと思います。
私が理解しているように、メソッドを返すSelf
ことは一種のジェネリックメソッドです。Self
多くのコンテキスト (クラス、構造体、プロトコルなど) で使用できますが、Self.Type
一致AnyClass
するのはクラスのみです。
私の場合、コンパイラはとそのすべてのサブクラスをSelf
参照していることを認識している必要があるため (拡張機能内にあるため)、に変換可能でなければなりません。UIViewController
UIViewController
Self.Type
AnyClass
コンパイラは追加の型分析を実行しないため、何か見逃していますか、それとも正しい動作Self
ですか?