在Swift中,Self.Type不能直接转换为ObjectiveC类扩展中的AnyClass

时间:2015-11-06 12:48:59

标签: ios objective-c swift type-inference swift-extensions

我正在尝试创建Fabric方法来创建具有正确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)
        }
    }
}

但编译器在Cannot convert value of type 'Self.Type' to expected argument type 'AnyClass' (aka 'AnyObject.Type')中发出错误: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执行任何其他类型分析?

2 个答案:

答案 0 :(得分:9)

这看起来像一个错误或(不必要的)限制,所以你可能 考虑在Apple提交错误报告。它只发生 对于返回类型为Self的类型方法。作为一种解决方法,你可以写 让clsName = NSStringFromClass(s​​elf as!AnyClass).componentsSeparatedByString("。")。last! 编译并似乎按预期工作。 但是有一种更简单的方法可以获得相同的结果: // Swift 2: let clsName = String(self) // Swift 3: let clsName = String(描述:self)

答案 1 :(得分:3)

也许这是一个错误,尝试强迫一个沮丧,这就是我必须让它工作的方式:

let clsName = NSStringFromClass(self as! AnyClass).componentsSeparatedByString(".").last!