2016-03-23 5 views
0

Возможно ли вернуть тип класса из функции?Swift - экземпляр класса из типа, возвращаемого функцией

Я пытаюсь сделать что-то вроде этого:

func giveMeAClass() -> AnyClass { 
    return String.self 
} 

let theClass = giveMeAClass() 

let instantiatedFromTheClass = theClass() 

let castedFromTheClass = someObject as! theClass 

EDIT:

Другой пример, когда я пытаюсь сделать что-то более полезное

class BaseModel { 
    var baseProperty: String! 
} 

class TextModel: BaseModel { 
    var textProperty: String! 
} 

class DateModel: BaseModel { 
    var dateProperty: NSDate! 
} 

class BaseCell<T: BaseModel>: UITableViewCell { 
    var model: T! 
} 

class TextCell: BaseCell<TextModel> { 

} 

class DateCell: BaseCell<DateModel> { 

} 

func getCellTypeForModel(model: BaseModel) -> ??? { 

    if model is TextModel { 
     return TextCell.Type // ??? 
    } 

    else if model is DateModel { 
     return DateCell.self // ??? 
    } 

    return BaseCell.somethingElse // ??? 
} 

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 

    let model = cellModels[indexPath.item] as! BaseModel 
    let cellType = getCellTypeForModel(anyModel) 
    let castedCell = tableView.dequeueReusableCellWithIdentifier("identifier", forIndexPath: indexPath) as! cellType 

    // give the model to the cell, customize it, etc 

    return castedCell 
} 
+0

'String' не является классом. Это значение-тип. –

ответ

2

При инициализации из метатипы , вам необходимо явно вызвать initializer. Например.

protocol SimplyInitializable { init() } 

extension String: SimplyInitializable {} 
extension Int: SimplyInitializable {} 

class Foo : SimplyInitializable { 
    let foo : Int 
    required init() { foo = 42 } 
} 

func getType<T: SimplyInitializable>(type: T.Type) -> SimplyInitializable.Type { 
    return type 
} 

/* example usage */ 
var MyType = getType(String) 
let foo = MyType.init() as! String // "", String 

MyType = getType(Int) 
let bar = MyType.init() as! Int // 0, Int 

MyType = getType(Foo) 
let baz = MyType.init() as! Foo 
baz.foo // 42 

Обратите внимание, что вам не нужна функция для присвоения метатипа, например.

let MyType2 : SimplyInitializable.Type = Foo.self 
let foobar = MyType2.init() 
+0

Спасибо. Не совсем то, что я ищу, я отредактирую свой ответ, чтобы показать более полный вариант использования. Между прочим, вам этот протокол не нужен. Вы можете просто сделать это: https://gist.github.com/johanhar/33823c396e8bfa697fb5 – Johannes

+2

@Johannes Happy помочь. Обратите внимание, что протокол в действительности имеет тонкое применение в приведенном выше примере. В вашей ссылке gist у нас нет слоя абстракции, а функция 'getType (..)' полностью эквивалентна установке метатипа непосредственно 'let MyType = Foo.self'. В этом случае 'MyType' имеет значение' Foo.Type' и, зная это _специфическое не общее представление о 'Foo'_, мы можем вызвать инициализатор' init() '. В приведенном выше примере протокола у нас есть слой абстракции с использованием 'SimplyInitializable.Type' в качестве метатипа, зная, что все типы, соответствующие' Simpl..', будут иметь инициализатор 'init()'. – dfri

+0

У вас есть точка, хорошее объяснение. Я отредактировал свой ответ на примере, который ближе к тому, что я на самом деле пытаюсь сделать – Johannes