2016-02-03 19 views
6

In Swift, diciamo che voglio aggiungere un metodo factory statica che restituisce un'istanza:Swift: Get classe corrente da un metodo statico

class MyClass { 
    static func getInstance() { 
    return MyClass(someProperty); 
    } 
} 

Ma cosa succede se io non voglio scrivere il nome della classe ? Esiste un equivalente di self ma per metodi e proprietà statici?

Stessa idea se voglio chiamare un altro metodo statico da un metodo statico:

class MyClass { 
    static func prepare(){ 
    //Something 
    } 

    static func doIt() { 
    MyClass.prepare(); 
    } 
} 

Posso fare questo senza usare MyClass esplicitamente?

risposta

4

auto lavora a metodi statici anche, in questo modo:

class MyClass { 
    static func prepare(){ 
    print("Hello"); 
    } 

    static func doIt() { 
    self.prepare(); 
    } 
} 
+0

Grazie. Che dire di 'self()'? Ottengo alcuni errori dicendo che ho bisogno di 'self.init', e quando lo faccio ottengo qualche altro errore che mi serve un inizializzatore' required' ... –

+0

self() non è possibile, ma mi chiedo perché vuoi fare quello? dfri descrive le migliori pratiche di cui sopra per creare pattern di progettazione di fabbrica. Ecco un altro esempio: https://github.com/ochococo/Design-Patterns-In-Swift/blob/master/source/creational/factory.swift – RobbeR

+0

L'unica ragione per cui sto facendo questo è perché il codice verrà copiato e distribuito per altre persone da usare. Ho pensato che meno cose fossero codificate, meglio è ... Grazie! –

0

Come RobberR scrive sopra, si potrebbe utilizzare per l'accesso self funzione statica di self e self.init(...) per il suo esempio di fabbrica. Nota che devi ancora specificare MyClass come tipo di ritorno nel tuo metodo di fabbrica.

In alternativa, un approccio più generico, è possibile consentire alla classe di conformarsi a un protocollo di fabbrica che contiene un'implementazione predefinita per il metodo factory. Con questo metodo, il metodo factory statico non è legato ad alcuna classe specifica, ma può essere accessibile a da qualsiasi classe conforme al protocollo di fabbrica (e un ulteriore protocollo di guida per gli inizializzatori comuni). configurazione

fabbrica:

protocol FactoryInitializers { 
    var commonProperty : Int { get set } 
    init(commonProperty: Int) 
} 

protocol FactoryMethods { 
    typealias T: FactoryInitializers 
    static var defaultStaticCommonProperty : Int { get } 
} 
extension FactoryMethods { 
    static func getInstance() -> T { 
     return T(commonProperty: defaultStaticCommonProperty) 
    } 
    static func getInstanceFor(commonProperty commonProperty: Int) -> T { 
     return T(commonProperty: commonProperty) 
    } 
} 

protocol Factory : FactoryMethods, FactoryInitializers { } 

Esempio conformità sono di classe: utilizzo

class MyClass : Factory { 
    typealias T = MyClass 
    static var defaultStaticCommonProperty : Int = 1 

    var commonProperty : Int = 0 

    required init(commonProperty: Int) { 
     self.commonProperty = commonProperty 
    } 
} 

class MyOtherClass : Factory { 
    typealias T = MyOtherClass 
    static var defaultStaticCommonProperty : Int = 10 

    var commonProperty : Int = 0 

    required init(commonProperty: Int) { 
     self.commonProperty = commonProperty 
    } 
} 

Esempio:

var foo = MyClass.getInstance() 
print(foo.dynamicType) // "MyClass" 
print(foo.commonProperty) // 1 
foo = MyClass.getInstanceFor(commonProperty: 5) 
print(foo.commonProperty) // 5 

var bar = MyOtherClass.getInstance() 
print(bar.dynamicType) // "MyOtherClass" 
print(bar.commonProperty) // 10 
0

È possibile definire un protocollo e utilizzare il swift generics come questo:

protocol Vehicle { 
    init() 
} 

class MyVehicleFactory<T:Vehicle> { 
    static func getInstance() -> T { 
    return T() 
    } 
} 

E le persone che hanno copiato il codice può fare questo:

class Car : Vehicle { 
    required init() { } 
} 
let car = MyVehicleFactory<Car>.getInstance();