2015-11-06 27 views
4

我試圖創建結構方法來創建具有正確的筆尖名稱(修復iOS8默認初始化程序問題)的UIViewController。要做到這一點我已經添加擴展名:Self.Type不能直接轉換爲AnyClass擴展到Objective-C類在swift

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

在我的情況下,編譯器應該知道,SelfUIViewController及其所有子類(因爲它是內部UIViewController擴展名),所以Self.Type必須可轉換爲AnyClass

因爲編譯器不爲Self執行任何其他類型分析,所以我錯過了什麼,或者它是正確的行爲?

回答

8

這看起來像一個錯誤或(不必要的)限制,所以你可能會考慮在蘋果提交一個錯誤報告 。對於返回類型爲Self的類型方法,僅發生 。作爲解決方法,您可以編寫

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

編譯並似乎按預期工作。

但有一個簡單的方法來獲得相同的結果:

// Swift 2: 
let clsName = String(self) 
// Swift 3: 
let clsName = String(describing: self) 
+2

哇,恭喜你在幾乎同一時間得到與我一樣的答案haha – Knight0fDragon

+0

對於Swift 3,最後一行應該是「let clsName = String(describe:self)」。 – RenniePet

+0

@RenniePet:的確,謝謝。 –

2

也許這是一個錯誤,請嘗試強制向下轉換,這就是我必須得到這個工作:

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