2014-11-07 11 views
36

Non è veloce la classe nidificata?Proprietà classe nidificate rapide

Ad esempio, non riesco ad accedere al test di proprietà della classe master dalla classe nidificata.

class master{ 
    var test = 2; 

    class nested{ 
    init(){ 
     let example = test; //this doesn't work 
    } 
    } 
} 

risposta

69

Le classi nidificate di Swift non sono come le classi nidificate di Java. Beh, sono come un tipo di classi nidificate di Java, ma non il tipo a cui stai pensando.

In Java, un'istanza di una classe interna ha automaticamente un riferimento a un'istanza della classe esterna (a meno che la classe interna non sia dichiarata static). Puoi creare un'istanza della classe interna solo se hai un'istanza della classe esterna. Ecco perché in Java dici qualcosa come this.new nested().

In Swift, un'istanza di una classe interna è indipendente da qualsiasi istanza della classe esterna. È come se tutte le classi interne di Swift venissero dichiarate usando Java static. Se si desidera che l'istanza della classe interna per avere un riferimento a un'istanza della classe esterna, è necessario renderlo esplicito:

class Master { 
    var test = 2; 

    class Nested{ 
     init(master: Master) { 
      let example = master.test; 
     } 
    } 

    func f() { 
     // Nested is in scope in the body of Master, so this works: 
     let n = Nested(master: self) 
    } 
} 

var m = Master() 
// Outside Master, you must qualify the name of the inner class: 
var n = Master.Nested(master:m) 

// This doesn't work because Nested isn't an instance property or function: 
var n2 = m.Nested() 

// This doesn't work because Nested isn't in scope here: 
var n3 = Nested(master: m) 
+3

Grazie, questo ha senso anche se è un po 'zoppo. Suppongo che, a causa di ciò, l'unica ragione per usare classi nidificate in swift sia quella di raggruppare le classi in un tipo di spazio dei nomi con la classe master come spazio dei nomi. – NJGUY

+0

All'interno del corpo di 'Master', questo funzionerebbe:' Nested (master: m) '? – Unheilig

+1

Sì, perché 'Nested' è all'interno del corpo di' Master'. –

3

Questa soluzione è una sorta di simile a come lo uso in C#, e io averlo testato con successo in Xcode.

Ecco la ripartizione del processo:

  1. La classe annidata deve essere reso opzionale in modo da non dover inizializzarlo, così ce n'è un '?' nella dichiarazione; se si inizializza sia la classe padre e la classe nidificato, si finisce con un effetto 'ricorsione' e viene generato un errore
  2. creare una funzione regolare che riceve un argomento dello stesso tipo come classe principale
  3. Passo che argomento della classe nidificata (può andare nell'inizializzatore normale dell'oggetto nidificato). - Dal momento che gli oggetti vengono passati per riferimento per impostazione predefinita, non c'è niente di speciale per ottenere la classe annidata per il collegamento alla classe padre
  4. Dentro la classe nidificata, è necessario una variabile dello stesso tipo come la vostra classe genitore

Da qui in poi allestisci tutto come faresti normalmente.

Nell'area di esecuzione del codice, anche l'oggetto della classe nidificata deve essere considerato opzionale (da qui il '?'). Se te ne dimentichi, Xcode lo aggiungerà comunque.

In questo esempio, ho voluto disegnare una parola chiave "set", in modo da quando ho impostato le variabili, posso tipo:

testClass.set.(and then a descriptive method name) 

Ecco il codice, e il suo obiettivo è quello di uscita di "test" in la console, dopo che il valore è stato impostato tramite l'oggetto nidificato:

class testClass 
{ 
    var test_string:String = "" 
    var set: class_set? 

    func construct_objects(argument: testClass) 
    { 
     self.set = class_set(argument: argument) 
    } 
    class class_set 
    { 
     var parent:testClass 
     init(argument: testClass) 
     { 
      parent = argument 
     } 
     func test_string_to_argument(argument: String) 
     { 
      parent.test_string = argument 
     } 
    } 
} 
var oTestClass = testClass() 
oTestClass.construct_objects(oTestClass) 
oTestClass.set?.test_string_to_argument("test") 
print(oTestClass.test_string) 
Problemi correlati