dynamicType +强制转换为协议会导致崩溃

时间:2015-10-27 16:40:43

标签: swift dynamictype

我有这些课程:

AppDataProtocol.swift

public protocol AppDataProtocol{

    var logoImagePath : String! {get}
    var logoTitle : String? {get}
    var logoSubtitle : String? {get}

    var categories : [MainMenuOption]! {get}

    static func contentElements(filter: ContentFilter?) -> [ContentElement]!
}

AppData.swift

class AppData{

   static var sharedData : AppDataProtocol!

   init(){}

}

CustomAppData.swift [符合AppDataProtocol的类]

class CustomAppData: AppData, AppDataProtocol {
// fulfills the AppDataProtocol, omitted for brevity
}

因此,给定这些类,我尝试动态设置类变量,如下所示:

AppData.sharedData = CustomAppData()

并像这样访问它:

// we need the class so we can call the class function
let appData = AppData.sharedData.dynamicType as! AppDataProtocol.Type 
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
                             /*CRASH!*/
let contentElements = appData.contentElements(nil)

通过在AppData(sharedData)的类变量中存储的实例上调用dynamicType,我应该得到符合AppDataProtocol的类,对吧?我认为问题是dynamicType实际上返回了Interface类型(即“AppDataProtocol”),我可能根本就不能调用任何东西。有人可以告诉我为什么这不起作用?

1 个答案:

答案 0 :(得分:1)

OP似乎希望有一个类变量,它包含一个符合协议的Type(即一个实际的类),但可能本身是变量的(即保持不同的Type s该协议在不同时间)。

问题在于

class AppData{
   static var sharedData : AppDataProtocol
   init(){}
}

将无法编译,因为sharedData未初始化。解决这个问题的一个方法是让它隐含地解开,正如他在问题中所做的那样,相信当他确实访问它时,设置好。这个问题是,当他实际访问变量dynamicType时,它并不是他所期望的 - 它实际上是ImplicitlyUnwrappedOptional<AppDataProtocol>.Type而不是AppDataProtocol.Type

解决方案只是声明static var sharedData : AppDataProtocol?而不是static var sharedData : AppDataProtocol!,然后在调用dynamicType之前解包它,因此:

let appData = (AppData.sharedData!).dynamicType // "CustomAppData.Type"

OP - 如果我对您的意图的假设偏离目标,请随时编辑...