2015-10-27 2 views
1

У меня есть эти классы: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 [Class который соответствует 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) 

Позвонив dynamicType на экземпляре хранящиеся в переменной класса AppData (sharedData), я должен получить класс, соответствующий AppDataProtocol, правильно? Я думаю, проблема в том, что dynamicType фактически возвращает тип интерфейса (т. Е. «AppDataProtocol»), и я, вероятно, не могу ничего называть сам по себе. Может кто-нибудь сказать мне, почему это не работает?

+0

Я не понимаю, что вы пытаетесь сделать. 'AppData.sharedData' не инициализирован и не имеет типа, только протокол, который вы хотите, чтобы он соответствовал. Будет ли остальная часть вашего вынужденного понижения когда-либо работать, будет спорным ... – Grimxn

+0

@Grimxn Это фактически инициализировано ... Посмотрите на строку в моем вопросе, в которой говорится: «AppData.sharedData = CustomAppData()» –

+0

Пропущено это. Почему вы инициализируете его вне класса? Поскольку вы это делаете, вы должны неявно разворачивать его, что означает, что 'AppData.sharedData.dynamicType' является' ImplicitlyUnwrappedOptional .Type', а не 'AppDataProtocol.Type', который, вероятно, не так, как вы ожидали ... – Grimxn

ответ

1

OP, кажется, хочет иметь иметь переменный класс, который содержит Type (т.е. фактического класса), который соответствует протоколу, но может быть сам переменным (т.е. имеют разные Type сек этого протокола в разное время).

Проблема заключается в том, что

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 - не стесняйтесь редактировать, если мое предположение о ваших намерениях off target ...

+0

Ты прибил его на голову. Еще раз спасибо! –

Смежные вопросы