10

正しい 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参照していることを認識している必要があるため (拡張機能内にあるため)、に変換可能でなければなりません。UIViewControllerUIViewControllerSelf.TypeAnyClass

コンパイラは追加の型分析を実行しないため、何か見逃していますか、それとも正しい動作Selfですか?

4

2 に答える 2