sport - ¿Cómo convertir AnyClass a una clase específica e iniciarlo dinámicamente en Swift?
suzuki swift sport (5)
En Object-C , almaceno objetos de clase en una matriz e inícielos dinámicamente como este:
self.controllers=@[[OneViewController class],[TwoViewController class]];
Class clz = self.controllers[index];
UIViewController *detailViewController = [[clz alloc] init];
En Swift lo intento de esta manera, pero genera un error:
var controllers:AnyClass[] = [OneViewController.self,TwoViewController.self]
var clz : AnyClass = controllers[index]
var instance = clz() // Error:''AnyObject'' is not constructible with ()
Me pregunto si hay una forma de convertir AnyClass a una clase específica. ¿O alguna otra buena idea?
Aquí hay una implementación pura y rápida de tipos de clases dinámicas. Requiere que las clases extiendan el mismo protocolo.
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
He encontrado una manera de resolver este problema:
var controllers:AnyClass[] = [OneViewController.self,TwoViewController.self]
var clz: NSObject.Type = controllers[0] as NSObject.Type
var con = clz()
recuerde agregar @objc en la clase de ViewController
Puede especificar que la matriz sea del tipo de superclase común, luego escriba que la deducción hace lo correcto (sintaxis de Beta-3):
let classArray: [UIViewController.Type] = [
OneViewController.self, TwoViewController.self
]
let controllerClass = classArray[index]
let controller = controllerClass.init()
Si las clases son todas las subclases NSObject de Objective-C, puedes hacer algo como esto (sí, los backticks son intencionales):
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)")
Debería salir:
dynamically created a string: Hello, an array: (
Swift
), and a dictionary: {
Goodbye = "Objective-C";
}
Me parece que debería haber una manera más elegante de hacer esto.
Una variable AnyClass
debe convertirse primero en un tipo específico para inicializar una instancia:
// 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)