2014-06-09 10 views
42

In Object-C devo conservare gli oggetti di classe in un array e li init in modo dinamico in questo modo:Come convertire AnyClass in una classe specifica e avviarlo dinamicamente in Swift?

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

In Swift provo in questo modo, ma genera un errore:

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

Mi chiedo se c'è un modo per convertire AnyClass in una classe specifica? O altre buone idee?

risposta

42

È possibile specificare la matrice di essere di tipo della superclasse comuni, quindi tipo di detrazione fa la cosa giusta (Beta-3 sintassi):

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

"L'inizializzazione da un valore di metatype deve fare riferimento a 'init' esplicitamente", quindi 'controllerClass.init()' lo è ora. – ctietze

0

Se le classi sono tutti Objective-C NSObject sottoclassi, si può fare qualcosa di simile (sì, gli apici inversi sono intenzionali):

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)") 

Dovrebbe uscita:

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

Mi sembra che ci dovrebbe essere un modo più elegante per farlo.

9

ho trovato un modo per risolvere questo problema:

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

ricordate di aggiungere @objc nella classe di ViewController

6

una variabile AnyClass deve prima essere colato in un tipo specifico al fine di inizializzare un i istanza:

// 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

Ecco un'implementazione rapida di tipi di classi dinamici. Richiede alle classi di estendere lo stesso protocollo.

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 
Problemi correlati