Подтвердить что ты не робот

Как преобразовать AnyClass в определенный класс и динамически инициализировать его в Swift?

В Object-C Я храню объекты класса в массиве и динамически инициализирую их следующим образом:

[email protected][[OneViewController class],[TwoViewController class]];
Class clz = self.controllers[index];
UIViewController *detailViewController = [[clz alloc] init];

В Swift я стараюсь, но это вызывает ошибку:

var controllers:AnyClass[] = [OneViewController.self,TwoViewController.self]
var clz : AnyClass = controllers[index]
var instance = clz() // Error:'AnyObject' is not constructible with ()

Интересно, есть ли способ конвертировать AnyClass в конкретный класс? Или любые другие хорошие идеи?

4b9b3361

Ответ 1

Вы можете указать массив, который будет иметь тип обычного суперкласса, затем введите вывод, который делает правильную вещь (синтаксис Beta-3):

let classArray: [UIViewController.Type] = [
    OneViewController.self, TwoViewController.self
]
let controllerClass = classArray[index]
let controller = controllerClass.init()

Ответ 2

Я нашел способ решить эту проблему:

var controllers:AnyClass[] = [OneViewController.self,TwoViewController.self]
var clz: NSObject.Type = controllers[0] as NSObject.Type
var con = clz()

Не забудьте добавить @objc в класс ViewController

Ответ 3

Переменная AnyClass должна быть сначала выбрана в определенный тип, чтобы инициализировать экземпляр:

// Code checked to run on xCode 7.1.1
import UIKit

var aClass: AnyClass = UIButton.self

// Error: 'init' is a member of the type...
// let doesNotWork = aClass.init()

// aClass must be casted first
var buttonClass = aClass as! UIButton.Type
var oneButton = buttonClass!.init()
var otherButton = buttonClass!.init(frame: CGRectZero)

Ответ 4

Вот чистая быстрая реализация динамических типов классов. Это требует, чтобы классы расширяли один и тот же протокол.

protocol X{var s:String{get};init(_ s:String)}
class A:X{var s:String;required init(_ s:String){self.s = s}}
class B:X{var s:String;required init(_ s:String){self.s = s}}
var instance:X
var classType:X.Type

classType = A.self
instance = classType.init("abc")
print(instance.s)//abc

classType = B.self
instance = classType.init("123")
print(instance.s)//123

Ответ 5

Если классы представляют собой подклассы Objective-C NSObject, вы можете сделать что-то вроде этого (да, обратные ссылки преднамеренно):

var constructors: (Void -> NSObject!)[] = [ NSMutableString.`new`, NSMutableArray.`new`, NSMutableDictionary.`new` ]

let string = constructors[0]()
(string as NSMutableString).appendString("Hello")

let array = constructors[1]()
(array as NSMutableArray).addObject("Swift")

let dictionary = constructors[2]()
(dictionary as NSMutableDictionary).setObject("Objective-C", forKey: "Goodbye")

NSLog("dynamically created a string: \(string), an array: \(array), and a dictionary: \(dictionary)")

Он должен выводить:

dynamically created a string: Hello, an array: (
    Swift
), and a dictionary: {
    Goodbye = "Objective-C";
}

Мне кажется, что должен быть более элегантный способ сделать это.